Example #1
0
    def __init__(self,
                 north=True,
                 reference_longitude=0,
                 reference_scale=45,
                 celestial=False):
        """
        :param north: whether to plot the north pole
        :param reference_longitude: the longitude that points to the right
        :param reference_scale: degrees of latitude per unit distance
        :param celestial: longitude increases clockwise around north pole
        """

        self.origin = SphericalPoint(0, 0)
        self._north = north
        self.reference_longitude = reference_longitude
        self.reference_scale = reference_scale
        self._celestial = celestial

        if self._north:
            if self.reference_scale >= 90:
                raise ProjectionError(
                    "Invalid reference scale {} for north pole".format(
                        self.reference_scale))
            self.origin_latitude = 90
        else:
            self.reference_scale = -self.reference_scale
            if self.reference_scale <= -90:
                raise ProjectionError(
                    "Invalid reference scale {} for south pole".format(
                        self.reference_scale))
            self.origin_latitude = -90

        self.reverse_polar_direction = not xor(self._north, self._celestial)
Example #2
0
    def map_meridian(self, longitude):
        p1 = SphericalPoint(longitude, self.min_latitude)
        p2 = SphericalPoint(longitude, self.max_latitude)
        l = self.map_line(Line(p1, p2))

        m = self.gridline_factory.meridian(longitude, l)
        m.border1 = "bottom"
        m.border2 = "top"
        m.tickangle1 = 270
        m.tickangle2 = 90
        return m
Example #3
0
 def test_projection(self):
     c = self.p(self.p.parallel_circle_center)
     self.assertEqual(self.p.cone_angle, 45)
     f = math.sin(math.radians(self.p.cone_angle))
     print f
     self.assertEqual(self.p(SphericalPoint(0, 45)), Point(0, 0))
     self.assertEqual(self.p(SphericalPoint(0, 50)), Point(0, 0.5))
     self.assertEqual(self.p(SphericalPoint(0, 35)), Point(0, -1))
     #a = 0.98861593*f*15
     a = f*15
     print a
     print c
     p = c + (Point(0, 0) - c).rotate(a)
Example #4
0
    def map_parallel(self, latitude):
        p1 = SphericalPoint(self.min_longitude, latitude)
        p2 = SphericalPoint(self.max_longitude, latitude)
        l = self.map_line(Line(p1, p2))
        if l.p1.x > l.p2.x:
            l.p1, l.p2 = l.p2, l.p1

        p = self.gridline_factory.parallel(latitude, l)
        p.border1 = "left"
        p.border2 = "right"
        p.tickangle1 = 180
        p.tickangle2 = 0
        return p
Example #5
0
    def map_meridian(self, longitude, longitude_offsets={}):
        offset = 0
        for l in sorted(longitude_offsets.keys(), reverse=True):
            if longitude % l == 0:
                offset = longitude_offsets[l]
                break

        if self.projection.reference_latitude > 0:
            p1 = SphericalPoint(longitude, self.min_latitude)
            p2 = SphericalPoint(longitude, self.max_latitude - offset)
        else:
            p1 = SphericalPoint(longitude, self.min_latitude + offset)
            p2 = SphericalPoint(longitude, self.max_latitude)

        l = self.map_line(Line(p1, p2))
        if self.bordered:
            intersections = self.line_intersect_borders(l)
            if not intersections:
                return None
            if len(intersections) == 1:
                if self.inside_maparea(l.p1):
                    p2, border2 = intersections[0]
                    p1, border1 = l.p1, None
                else:
                    p1, border1 = intersections[0]
                    p2, border2 = l.p2, None
            else:
                p1, border1 = intersections[0]
                p2, border2 = intersections[1]

            if p1.y < p2.y:
                p1, p2 = p2, p1
                border1, border2 = border2, border1

            l.p1 = p1
            l.p2 = p2
        else:
            border1 = "bottom"
            border2 = "top"

        m = self.gridline_factory.meridian(longitude, l)
        m.border1 = border1
        m.border2 = border2
        m.tickangle1 = l.angle + 180
        m.tickangle2 = l.angle
        if self.gridline_factory.rotate_meridian_labels:
            m.labelangle1 = l.angle - 90
            m.labelangle2 = l.angle - 90
        return m
Example #6
0
 def inverse_project(self, point):
     if self.celestial:
         longitude = -self.center_longitude - self.reference_scale * point.x / self.lateral_scale
     else:
         longitude = self.center_longitude + self.reference_scale * point.x / self.lateral_scale
     latitude = point.y * self.reference_scale
     return SphericalPoint(longitude, latitude)
Example #7
0
    def map_parallel(self, latitude):
        c = Circle(SphericalPoint(0, self.projection.origin_latitude),
                   self.projection.origin_latitude - latitude)
        c = self.map_circle(c)

        crossings = self.circle_intersect_borders(c)
        if crossings:
            parallels = []
            for i in range(len(crossings)):
                a1, c1, b1 = crossings[i - 1]
                a2, c2, b2 = crossings[i]
                if a1 > a2:
                    a2 += 360.0
                aavg = math.radians(0.5 * (a1 + a2))
                pavg = c.center + Point(c.radius * math.cos(aavg),
                                        c.radius * math.sin(aavg))
                if self.inside_maparea(pavg):
                    arc = Arc(c.center, c.radius, a1, a2)
                    p = self.gridline_factory.parallel(latitude, arc)
                    parallels.append(p)
        else:
            p = self.gridline_factory.parallel(latitude, c)
            parallels = [p]

        return parallels
Example #8
0
 def test_latitude(self):
     self.assertEqual(self.p.project(SphericalPoint(0, 50)), Point(1, 0))
     self.assertEqual(self.p.project(SphericalPoint(90, 50)), Point(0, 1))
     self.assertEqual(self.p.project(SphericalPoint(180, 50)), Point(-1, 0))
     self.assertEqual(self.p.project(SphericalPoint(270, 50)), Point(0, -1))
     self.p.celestial = True
     self.assertEqual(self.p.project(SphericalPoint(0, 50)), Point(1, 0))
     self.assertEqual(self.p.project(SphericalPoint(90, 50)), Point(0, -1))
     self.assertEqual(self.p.project(SphericalPoint(180, 50)), Point(-1, 0))
     self.assertEqual(self.p.project(SphericalPoint(270, 50)), Point(0, 1))
Example #9
0
    def map_meridian(self, longitude, longitude_offsets={}):
        """Returns the exact line to draw for a meridian"""
        offset = 0
        for l in sorted(longitude_offsets.keys(), reverse=True):
            if longitude % l == 0:
                offset = longitude_offsets[l]
                break

        if self.projection.north:
            p1 = SphericalPoint(longitude,
                                self.projection.origin_latitude - offset)
        else:
            p1 = SphericalPoint(longitude,
                                self.projection.origin_latitude + offset)

        if self.projection.north:
            p2 = SphericalPoint(longitude, self.min_latitude)
        else:
            p2 = SphericalPoint(longitude, self.max_latitude)

        l = self.map_line(Line(p1, p2))
        if self.bordered:
            p2, border2 = self.line_intersect_borders(l)[0]
            l.p2 = p2
        else:
            border2 = "bottom"

        m = self.gridline_factory.meridian(longitude, l)
        m.border2 = border2

        if xor(self.projection.north, not self.projection.celestial):
            m.tickangle2 = -longitude + self.projection.reference_longitude
        else:
            m.tickangle2 = longitude - self.projection.reference_longitude

        if self.gridline_factory.rotate_meridian_labels:
            m.labelpos2 = 270
            m.labelangle2 = l.angle + 90
        else:
            pass

        return m
Example #10
0
def get_constellation_boundaries_for_area(min_longitude,
                                          max_longitude,
                                          min_latitude,
                                          max_latitude,
                                          epoch=REFERENCE_EPOCH):
    # Convert longitude to 0-360 values
    # TODO: sometimes boundaries cross the map but have no vertices within the map area + margin and are not plotted
    min_longitude = ensure_angle_range(min_longitude)
    max_longitude = ensure_angle_range(max_longitude)
    if max_longitude == min_longitude:
        max_longitude += 360

    db = SkyMapDatabase()
    q = "SELECT * FROM skymap_constellation_boundaries WHERE"

    if min_longitude < max_longitude:
        q += " ((ra1>={0} AND ra1<={1}".format(min_longitude, max_longitude)
    else:
        q += " (((ra1>={0} OR ra1<={1})".format(min_longitude, max_longitude)

    q += " AND dec1>={0} AND dec1<={1}) OR".format(min_latitude, max_latitude)

    if min_longitude < max_longitude:
        q += " (ra2>={0} AND ra2<={1}".format(min_longitude, max_longitude)
    else:
        q += " ((ra2>={0} OR ra2<={1})".format(min_longitude, max_longitude)

    q += " AND dec2>={0} AND dec2<={1}))".format(min_latitude, max_latitude)

    res = db.query(q)

    result = []
    pc = PrecessionCalculator(CONST_BOUND_EPOCH, epoch)
    for row in res:
        p1 = SphericalPoint(row['ra1'], row['dec1'])
        p2 = SphericalPoint(row['ra2'], row['dec2'])
        e = BoundaryEdge(p1, p2)
        e.precess(pc)
        result.append(e)

    db.close()
    return result
Example #11
0
    def inverse_project(self, point):
        rho = self.origin.distance(point)
        theta = ensure_angle_range(math.degrees(math.atan2(point.y, point.x)))

        if self.reverse_polar_direction:
            longitude = ensure_angle_range(-theta + self.reference_longitude)
        else:
            longitude = ensure_angle_range(theta + self.reference_longitude)

        return SphericalPoint(
            longitude, -rho * self.reference_scale + self.origin_latitude)
Example #12
0
def get_milky_way_curve(id):
    db = SkyMapDatabase()
    q = "SELECT * FROM milkyway WHERE curve_id={0} ORDER BY id ASC".format(id)
    result = db.query(q)
    curve = []
    for row in result:
        curve.append(SphericalPoint(row['ra'], row['dec']))
    if curve[0] == curve[-1]:
        curve = curve[:-1]
    db.close()
    return curve
Example #13
0
    def test_inverse_project(self):
        self.assertEqual(self.p.inverse_project(Point(1, 0)), SphericalPoint(0, 50))
        self.assertEqual(self.p.inverse_project(Point(0, 1)), SphericalPoint(90, 50))
        self.assertEqual(self.p.inverse_project(Point(-1, 0)), SphericalPoint(180, 50))
        self.assertEqual(self.p.inverse_project(Point(0, -1)), SphericalPoint(270, 50))

        p = SphericalPoint(225, 76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)

        self.p.celestial = True
        self.assertEqual(self.p.inverse_project(Point(1, 0)), SphericalPoint(0, 50))
        self.assertEqual(self.p.inverse_project(Point(0, 1)), SphericalPoint(270, 50))
        self.assertEqual(self.p.inverse_project(Point(-1, 0)), SphericalPoint(180, 50))
        self.assertEqual(self.p.inverse_project(Point(0, -1)), SphericalPoint(90, 50))

        p = SphericalPoint(225, 76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)
Example #14
0
    def inverse_project(self, point):
        rho = self.reference_scale * numpy.sign(
            self.n) * math.sqrt(point.x**2 + (self.rho_0 - point.y)**2)
        theta = math.degrees(math.atan2(point.x, self.rho_0 - point.y))

        if self.celestial:
            longitude = self.reference_longitude - theta / self.n
        else:
            longitude = self.reference_longitude + theta / self.n
        latitude = math.degrees(self.G - rho)

        return SphericalPoint(longitude, latitude)
Example #15
0
    def precess(self, pc):
        if not self.interpolated_points:
            self.interpolated_points = self.interpolate_points()

        precessed_points = []
        for p in self.interpolated_points:
            pra, pdec = pc.precess(p.ra, p.dec)
            precessed_points.append(SphericalPoint(pra, pdec))

        self.epoch = pc.epoch2
        self.p1 = precessed_points[0]
        self.p2 = precessed_points[-1]
        self.interpolated_points = precessed_points
Example #16
0
    def draw_internal_parallel_ticks(self,
                                     longitude,
                                     angle=90,
                                     labels=False,
                                     label_angle=None):
        reference_meridian = self.map_meridian(longitude)
        tickangle = reference_meridian.meridian.angle + angle
        start_latitude = self.gridline_factory.parallel_tick_interval * math.ceil(
            self.min_latitude / self.gridline_factory.parallel_tick_interval)
        for latitude in numpy.arange(
                start_latitude, self.max_latitude,
                self.gridline_factory.parallel_tick_interval):
            if latitude in [-90, 90]:
                continue
            p1 = self.projection(SphericalPoint(longitude, latitude))
            if not self.inside_maparea(p1):
                continue
            delta = Point(1, 0).rotate(tickangle)

            if latitude % self.gridline_factory.parallel_line_interval == 0:
                ticksize = 0
            elif latitude % self.gridline_factory.parallel_marked_tick_interval == 0:
                ticksize = self.gridline_factory.marked_ticksize
            else:
                ticksize = self.gridline_factory.unmarked_ticksize

            if ticksize > 0:
                p2 = p1 + ticksize * delta
                self.draw_line(
                    Line(p1, p2),
                    linewidth=self.gridline_factory.gridline_thickness)

            if labels and latitude % self.gridline_factory.parallel_line_interval == 0:
                p3 = p1 + 0.75 * delta
                text = "{}\\textdegree".format(int(abs(latitude)))
                if abs < 0:
                    text = "--" + text
                else:
                    text = "+" + text
                if label_angle is None:
                    label_angle = tickangle
                l = Label(p3, text, label_angle, "tiny", angle=0, fill="white")
                self.draw_label(l)
Example #17
0
def extract_point(line):
    point_pattern = "^[A-Z]+\s(\d\d \d\d \d\d), (\-?)(\d\d \d\d)$"
    m = re.search(point_pattern, line)
    try:
        long = m.groups()[0]
        latsign = m.groups()[1]
        lat = m.groups()[2]

        if latsign == "-":
            latsign = -1
        else:
            latsign = 1

        h, m, s = (int(x) for x in long.split())
        longitude = HourAngle(h, m, s).to_degrees()

        d, m = (int(x) for x in lat.split())
        latitude = DMSAngle(degrees=d, minutes=m, sign=latsign).to_degrees()

        return SphericalPoint(longitude, latitude)
    except AttributeError:
        return None
Example #18
0
    def __init__(self,
                 center,
                 standard_parallel1,
                 standard_parallel2,
                 reference_scale=50,
                 celestial=False):
        self.celestial = celestial

        self.reference_longitude = center[0]
        self.reference_latitude = center[1]
        self.standard_parallel1 = standard_parallel1
        self.standard_parallel2 = standard_parallel2
        self.reference_scale = abs(math.radians(reference_scale))
        self.cone_angle = 90 - 0.5 * abs(self.standard_parallel1 +
                                         self.standard_parallel2)

        # Calculate projection parameters
        phi_1 = math.radians(self.standard_parallel1)
        phi_2 = math.radians(self.standard_parallel2)
        self.n = (math.cos(phi_1) - math.cos(phi_2)) / (phi_2 - phi_1)
        self.G = math.cos(phi_1) / self.n + phi_1
        self.rho_0 = (self.G - math.radians(
            self.reference_latitude)) / self.reference_scale
        self.parallel_circle_center = SphericalPoint(0, math.degrees(self.G))
Example #19
0
    def test_inverse_projection(self):
        self.assertEqual(self.p(Point(0, 0), inverse=True), SphericalPoint(0, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(15, 45)), inverse=True), SphericalPoint(15, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(-15, 45)), inverse=True), SphericalPoint(-15, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(29, 32)), inverse=True), SphericalPoint(29, 32))

        self.p.celestial = True
        self.assertEqual(self.p(Point(0, 0), inverse=True), SphericalPoint(0, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(15, 45)), inverse=True), SphericalPoint(15, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(-15, 45)), inverse=True), SphericalPoint(-15, 45))
        self.assertEqual(self.p(self.p(SphericalPoint(29, 32)), inverse=True), SphericalPoint(29, 32))
Example #20
0
 def test_latitude(self):
     self.assertEqual(self.p.project(SphericalPoint(0, 30)), Point(0, 1))
     self.assertEqual(self.p.project(SphericalPoint(0, -30)), Point(0, -1))
Example #21
0
 def test_longitude(self):
     self.assertEqual(self.p.project(SphericalPoint(0, 0)), Point(0, 0))
     self.assertEqual(self.p.project(SphericalPoint(30, 0)), Point(1, 0))
     self.assertEqual(self.p.project(SphericalPoint(-30, 0)), Point(-1, 0))
Example #22
0
 def test_other_scale(self):
     self.p = AzimuthalEquidistantProjection(reference_longitude=0, reference_scale=80.0/190.0)
     self.assertEqual(self.p.project(SphericalPoint(0, 50)), Point(95, 0))
Example #23
0
 def test_pole(self):
     self.assertEqual(self.p.project(SphericalPoint(0, 90)), self.origin)
Example #24
0
    def test_reference_longitude(self):
        self.p.reference_longitude = 40

        self.assertEqual(self.origin.distance(self.p.project(SphericalPoint(0, 50))), 1.0)
        self.assertEqual(self.p.project(SphericalPoint(40, 50)), Point(1, 0))
        self.assertEqual(self.p.project(SphericalPoint(130, 50)), Point(0, 1))
        self.assertEqual(self.p.project(SphericalPoint(220, 50)), Point(-1, 0))
        self.assertEqual(self.p.project(SphericalPoint(310, 50)), Point(0, -1))

        p = SphericalPoint(225, 76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)

        self.p.celestial = True
        self.assertEqual(self.p.project(SphericalPoint(40, 50)), Point(1, 0))
        self.assertEqual(self.p.project(SphericalPoint(130, 50)), Point(0, -1))
        self.assertEqual(self.p.project(SphericalPoint(220, 50)), Point(-1, 0))
        self.assertEqual(self.p.project(SphericalPoint(310, 50)), Point(0, 1))

        p = SphericalPoint(225, 76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)

        self.p.celestial = False
        self.p.reference_longitude = -40
        self.assertEqual(self.p.project(SphericalPoint(-40, 50)), Point(1, 0))
        self.assertEqual(self.p.project(SphericalPoint(50, 50)), Point(0, 1))
        self.assertEqual(self.p.project(SphericalPoint(140, 50)), Point(-1, 0))
        self.assertEqual(self.p.project(SphericalPoint(230, 50)), Point(0, -1))
Example #25
0
def azimuthal_map(chart_number, chart_side, north, delta=None):
    offset = 23
    latitude_range = 12
    if north:
        reference_longitude = 270
    else:
        reference_longitude = 90

    if delta is not None:
        origin_x = 5 * MM_PER_DEGREE + delta
    else:
        origin_x = 5 * MM_PER_DEGREE

    if chart_side == 'left':
        fn = "{:02}A".format(chart_number)
        f = leftfigure(fn)
        map_llcorner = LMAP_LLCORNER + Point(7, LEGEND_HEIGHT + offset)
        map_urcorner = map_llcorner + Point(10 * MM_PER_DEGREE,
                                            latitude_range * MM_PER_DEGREE)
        map_origin = map_llcorner + Point(origin_x,
                                          0.5 * latitude_range * MM_PER_DEGREE)
    else:
        fn = "{:02}B".format(chart_number)
        f = rightfigure(fn)
        map_lrcorner = RMAP_LLCORNER + Point(LEGEND_WIDTH - 7, 0) + Point(
            0, LEGEND_HEIGHT + offset)
        map_llcorner = map_lrcorner + Point(-10 * MM_PER_DEGREE, 0)
        map_urcorner = map_lrcorner + Point(0, latitude_range * MM_PER_DEGREE)
        map_origin = map_lrcorner + Point(-origin_x,
                                          0.5 * latitude_range * MM_PER_DEGREE)

    m = AzimuthalEquidistantMapArea(map_llcorner,
                                    map_urcorner,
                                    hmargin=MAP_HMARGIN,
                                    vmargin=MAP_VMARGIN,
                                    origin=map_origin,
                                    north=north,
                                    reference_longitude=reference_longitude,
                                    latitude_range=latitude_range,
                                    celestial=True,
                                    box=False)

    if delta is None:
        if chart_side == "left":
            if north:
                p1 = m.projection(SphericalPoint(90, 84))
            else:
                p1 = m.projection(SphericalPoint(270, -84))
            delta = map_llcorner.x - (map_origin.x + p1.x)
        else:
            if north:
                p1 = m.projection(SphericalPoint(270, 84))
            else:
                p1 = m.projection(SphericalPoint(90, -84))
            delta = -(map_lrcorner.x - (map_origin.x + p1.x))
        return azimuthal_map(chart_number, chart_side, north, delta)

    f.add(m)

    m.bordered = False

    m.gridline_factory.meridian_line_interval = 15
    m.gridline_factory.meridian_marked_tick_interval = 15
    m.gridline_factory.meridian_tick_interval = 15
    m.gridline_factory.parallel_line_interval = 1
    m.gridline_factory.parallel_marked_tick_interval = 1
    m.gridline_factory.parallel_tick_interval = 1

    m.gridline_factory.marked_ticksize = 0
    m.gridline_factory.unmarked_ticksize = 0
    m.gridline_factory.fixed_tick_reach = False

    m.gridline_factory.label_distance = 1

    m.gridline_factory.rotate_meridian_labels = True
    m.gridline_factory.meridian_labeltextfunc = azimuthal_meridian_label
    m.gridline_factory.rotate_poles = True
    m.gridline_factory.pole_marker_size = 1

    m.min_longitude = 0
    m.max_longitude = 360
    if north:
        m.min_latitude = 84
        m.max_latitude = 90
    else:
        m.min_latitude = -90
        m.max_latitude = -84

    return f, m
Example #26
0
    def draw_coordinate_system(self,
                               transformation,
                               linewidth=0.3,
                               dashed='dashed',
                               tickinterval=None,
                               poles=False):
        points = []
        for longitude in numpy.arange(0, 360.1, 0.251):
            p = transformation(SphericalPoint(longitude, 0))
            points.append(
                SphericalPoint(self.projection.reduce_longitude(p.longitude),
                               p.latitude))

        points_to_draw = []
        for i in range(len(points)):
            prev_p = points[i - 1]
            p = points[i]
            if i + 1 == len(points):
                next_p = points[0]
            else:
                next_p = points[i + 1]

            if self.bordered:
                prev_p = self.map_point(prev_p)
                p = self.map_point(p)
                next_p = self.map_point(next_p)

                if self.inside_maparea(prev_p) or self.inside_maparea(
                        p) or self.inside_maparea(next_p):
                    points_to_draw.append(p)
            else:
                prevpinside = self.inside_coordinate_range(prev_p)
                pinside = self.inside_coordinate_range(p)
                nextpinside = self.inside_coordinate_range(next_p)
                if prevpinside or pinside or nextpinside:
                    points_to_draw.append(self.map_point(p))

        points_to_draw = sorted(points_to_draw, key=attrgetter('x'))
        if points_to_draw:
            self.draw_polygon(points_to_draw,
                              linewidth=linewidth,
                              dashed=dashed)

        # Ticks
        if tickinterval is not None:
            for i in range(360 / int(tickinterval)):
                l = i * tickinterval
                p = transformation(SphericalPoint(l, 0))
                p.longitude = self.projection.reduce_longitude(p.longitude)
                if self.bordered:
                    p = self.map_point(p)
                    if not self.inside_maparea(p):
                        continue
                else:
                    if not self.inside_coordinate_range(p):
                        continue
                    p = self.map_point(p)

                v = self.map_point(transformation(SphericalPoint(l + 1,
                                                                 0))) - p
                v = v.rotate(90) / v.norm
                tp1 = p + 0.5 * v
                tp2 = p - 0.5 * v
                lp = p + 0.8 * v
                tick = Line(tp1, tp2)
                self.draw_line(tick, linewidth=linewidth)
                self.draw_label(
                    Label(lp,
                          "\\textit{{{}\\textdegree}}".format(l),
                          270,
                          "miniscule",
                          angle=tick.angle - 90,
                          fill="white"))

        # Poles
        if poles:
            p = transformation(SphericalPoint(0, 90))
            np = self.map_point(p)
            if self.gridline_factory.rotate_poles:
                delta1 = self.map_point(p + SphericalPoint(1, 0)) - np
                delta2 = self.map_point(p + SphericalPoint(0, 1)) - np
            else:
                delta1 = Point(1, 0)
                delta2 = Point(0, 1)

            delta1 *= self.gridline_factory.pole_marker_size / delta1.norm
            delta2 *= self.gridline_factory.pole_marker_size / delta2.norm

            if self.inside_maparea(np):
                bl1 = Line(np + 1.25 * delta1, np - 1.25 * delta1)
                l1 = Line(np + delta1, np - delta1)
                bl2 = Line(np + 1.25 * delta2, np - 1.25 * delta2)
                l2 = Line(np + delta2, np - delta2)
                self.draw_line(bl1, linewidth=3 * linewidth, color="white")
                self.draw_line(bl2, linewidth=3 * linewidth, color="white")
                self.draw_line(
                    l1, linewidth=self.gridline_factory.gridline_thickness)
                self.draw_line(
                    l2, linewidth=self.gridline_factory.gridline_thickness)

            p = transformation(SphericalPoint(0, -90))
            sp = self.map_point(p)
            if self.gridline_factory.rotate_poles:
                delta1 = self.map_point(p + SphericalPoint(1, 0)) - sp
                delta2 = self.map_point(p + SphericalPoint(0, 1)) - sp
            else:
                delta1 = Point(1, 0)
                delta2 = Point(0, 1)

            delta1 *= self.gridline_factory.pole_marker_size / delta1.norm
            delta2 *= self.gridline_factory.pole_marker_size / delta2.norm

            if self.inside_maparea(sp):
                bl1 = Line(sp + 1.25 * delta1, sp - 1.25 * delta1)
                l1 = Line(sp + delta1, sp - delta1)
                bl2 = Line(sp + 1.25 * delta2, sp - 1.25 * delta2)
                l2 = Line(sp + delta2, sp - delta2)
                self.draw_line(bl1, linewidth=3 * linewidth, color="white")
                self.draw_line(bl2, linewidth=3 * linewidth, color="white")
                self.draw_line(
                    l1, linewidth=self.gridline_factory.gridline_thickness)
                self.draw_line(
                    l2, linewidth=self.gridline_factory.gridline_thickness)
Example #27
0
    def test_south_pole(self):
        self.p = AzimuthalEquidistantProjection(north=False, reference_longitude=0, reference_scale=40)

        # Pole
        self.assertEqual(self.p.project(SphericalPoint(0, -90)), self.origin)

        # Project
        self.assertEqual(self.p.project(SphericalPoint(0, -50)), Point(1, 0))
        self.assertEqual(self.p.project(SphericalPoint(90, -50)), Point(0, -1))
        self.assertEqual(self.p.project(SphericalPoint(180, -50)), Point(-1, 0))
        self.assertEqual(self.p.project(SphericalPoint(270, -50)), Point(0, 1))
        self.p.celestial = True
        self.assertEqual(self.p.project(SphericalPoint(0, -50)), Point(1, 0))
        self.assertEqual(self.p.project(SphericalPoint(90, -50)), Point(0, 1))
        self.assertEqual(self.p.project(SphericalPoint(180, -50)), Point(-1, 0))
        self.assertEqual(self.p.project(SphericalPoint(270, -50)), Point(0, -1))

        # Inverse project
        self.p.celestial = False
        self.assertEqual(self.p.inverse_project(Point(1, 0)), SphericalPoint(0, -50))
        self.assertEqual(self.p.inverse_project(Point(0, -1)), SphericalPoint(90, -50))
        self.assertEqual(self.p.inverse_project(Point(-1, 0)), SphericalPoint(180, -50))
        self.assertEqual(self.p.inverse_project(Point(0, 1)), SphericalPoint(270, -50))
        p = SphericalPoint(225, -76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)

        self.p.celestial = True
        self.assertEqual(self.p.inverse_project(Point(1, 0)), SphericalPoint(0, -50))
        self.assertEqual(self.p.inverse_project(Point(0, 1)), SphericalPoint(90, -50))
        self.assertEqual(self.p.inverse_project(Point(-1, 0)), SphericalPoint(180, -50))
        self.assertEqual(self.p.inverse_project(Point(0, -1)), SphericalPoint(270, -50))
        p = SphericalPoint(225, -76)
        pp = self.p.project(p)
        ppp = self.p.inverse_project(pp)
        self.assertEqual(p, ppp)
Example #28
0
 def position(self):
     """Returns the position of the star in degrees"""
     return SphericalPoint(self.right_ascension, self.declination)
Example #29
0
def conic_map(chart_number,
              chart_side,
              min_longitude,
              max_longitude,
              min_latitude,
              max_latitude,
              meridian_interval,
              offset,
              delta=None):
    latitude_range = max_latitude - min_latitude
    center_latitude = min_latitude + 0.5 * latitude_range

    if delta is not None:
        offset += delta

    if chart_side == 'left':
        fn = "{:02}A".format(chart_number)
        f = leftfigure(fn)
        map_llcorner = LMAP_LLCORNER + Point(0, LEGEND_HEIGHT + offset)
        map_urcorner = map_llcorner + Point(LEGEND_WIDTH,
                                            latitude_range * MM_PER_DEGREE)
        center_longitude = min_longitude
        map_origin = map_llcorner + Point(LEGEND_WIDTH,
                                          0.5 * latitude_range * MM_PER_DEGREE)
    else:
        fn = "{:02}B".format(chart_number)
        f = rightfigure(fn)
        map_llcorner = RMAP_LLCORNER + Point(0, LEGEND_HEIGHT + offset)
        map_urcorner = map_llcorner + Point(LEGEND_WIDTH,
                                            latitude_range * MM_PER_DEGREE)
        center_longitude = max_longitude
        map_origin = map_llcorner + Point(0,
                                          0.5 * latitude_range * MM_PER_DEGREE)

    sp1 = min_latitude + int(round(latitude_range / 6.0))
    sp2 = min_latitude + int(round(5.0 * latitude_range / 6.0))

    m = EquidistantConicMapArea(map_llcorner,
                                map_urcorner,
                                hmargin=MAP_HMARGIN,
                                vmargin=MAP_VMARGIN,
                                center=(center_longitude, center_latitude),
                                standard_parallel1=sp1,
                                standard_parallel2=sp2,
                                latitude_range=latitude_range,
                                origin=map_origin,
                                celestial=True,
                                box=False)

    # Determine correct origin for south conic maps
    if center_latitude < 0 and delta is None:
        p1 = m.projection(SphericalPoint(max_longitude, min_latitude))
        p2 = m.projection(SphericalPoint(min_longitude, min_latitude))
        delta = abs(p1.y - p2.y)
        return conic_map(chart_number, chart_side, min_longitude,
                         max_longitude, min_latitude, max_latitude,
                         meridian_interval, offset, delta)

    f.add(m)

    m.bordered = False

    m.gridline_factory.meridian_line_interval = meridian_interval
    m.gridline_factory.meridian_marked_tick_interval = meridian_interval
    m.gridline_factory.meridian_tick_interval = meridian_interval
    m.gridline_factory.parallel_line_interval = 1
    m.gridline_factory.parallel_marked_tick_interval = 1
    m.gridline_factory.parallel_tick_interval = 1

    m.gridline_factory.marked_ticksize = 0
    m.gridline_factory.unmarked_ticksize = 0
    m.gridline_factory.fixed_tick_reach = False

    m.gridline_factory.label_distance = 1

    m.gridline_factory.rotate_parallel_labels = True

    m.gridline_factory.rotate_meridian_labels = True
    m.gridline_factory.meridian_labeltextfunc = meridian_label
    m.gridline_factory.rotate_poles = True
    m.gridline_factory.pole_marker_size = 1

    m.min_longitude = min_longitude
    m.max_longitude = max_longitude
    m.min_latitude = min_latitude
    m.max_latitude = max_latitude

    return f, m
Example #30
0
    def map_parallel(self, latitude):
        p = SphericalPoint(0, latitude)
        radius = p.distance(self.projection.parallel_circle_center)
        center = self.projection.parallel_circle_center
        c = Circle(center, radius)
        c = self.map_circle(c)

        if self.bordered:
            crossings = self.circle_intersect_borders(c)
            if crossings:
                parallels = []
                for i in range(len(crossings)):
                    a1, c1, b1 = crossings[i - 1]
                    a2, c2, b2 = crossings[i]
                    if a1 > a2:
                        a2 += 360.0
                    aavg = math.radians(0.5 * (a1 + a2))
                    pavg = c.center + Point(c.radius * math.cos(aavg),
                                            c.radius * math.sin(aavg))
                    if self.inside_maparea(pavg):
                        arc = Arc(c.center, c.radius, a1, a2)
                        p = self.gridline_factory.parallel(latitude, arc)

                        p.border1 = b1
                        p.tickangle1 = a1 + 90
                        if self.gridline_factory.rotate_parallel_labels:
                            if latitude > 0:
                                p.labelangle1 = a1 + 90
                            else:
                                p.labelangle1 = a1 - 90
                        else:
                            p.labelangle1 = 0

                        p.border2 = b2
                        p.tickangle2 = a2 + 90
                        if self.gridline_factory.rotate_parallel_labels:
                            if latitude > 0:
                                p.labelangle2 = a2 + 90
                            else:
                                p.labelangle2 = a2 - 90
                        else:
                            p.labelangle2 = 0
                        parallels.append(p)
            else:
                if self.inside_maparea(c.center):
                    p = self.gridline_factory.parallel(latitude, c)
                    parallels = [p]
                else:
                    parallels = []
        else:
            if self.projection.reference_latitude > 0:
                start_angle = self.map_meridian(
                    self.min_longitude).meridian.angle + 180
                stop_angle = self.map_meridian(
                    self.max_longitude).meridian.angle + 180
            else:
                start_angle = self.map_meridian(
                    self.max_longitude).meridian.angle
                stop_angle = self.map_meridian(
                    self.min_longitude).meridian.angle
            a = Arc(c.center, c.radius, start_angle, stop_angle)
            p = self.gridline_factory.parallel(latitude, a)

            if self.projection.reference_latitude > 0:
                p.border1 = 'right'
            else:
                p.border1 = 'left'

            p.tickangle1 = start_angle + 90

            if self.gridline_factory.rotate_parallel_labels:
                if self.projection.reference_latitude > 0:
                    p.labelangle1 = start_angle + 90
                else:
                    p.labelangle1 = start_angle - 90
            else:
                p.labelangle1 = 0

            if self.projection.reference_latitude > 0:
                p.border2 = 'left'
            else:
                p.border2 = 'right'

            p.tickangle2 = stop_angle - 90

            if self.gridline_factory.rotate_parallel_labels:
                if self.projection.reference_latitude > 0:
                    p.labelangle2 = stop_angle + 90
                else:
                    p.labelangle2 = stop_angle - 90
            else:
                p.labelangle2 = 0

            parallels = [p]

        return parallels