std::shared_ptr<TileData> TopoJsonSource::parse(const TileTask& _task,
                                                const MapProjection& _projection) const {

    auto& task = static_cast<const DownloadTileTask&>(_task);

    std::shared_ptr<TileData> tileData = std::make_shared<TileData>();

    // Parse data into a JSON document
    const char* error;
    size_t offset;
    auto document = JsonParseBytes(task.rawTileData->data(), task.rawTileData->size(), &error, &offset);

    if (error) {
        LOGE("Json parsing failed on tile [%s]: %s (%u)", task.tileId().toString().c_str(), error, offset);
        return tileData;
    }

    // Transform JSON data into a TileData using TopoJson functions
    BoundingBox tileBounds(_projection.TileBounds(task.tileId()));
    glm::dvec2 tileOrigin = {tileBounds.min.x, tileBounds.max.y*-1.0};
    double tileInverseScale = 1.0 / tileBounds.width();

    const auto projFn = [&](glm::dvec2 _lonLat){
        glm::dvec2 tmp = _projection.LonLatToMeters(_lonLat);
        return Point {
            (tmp.x - tileOrigin.x) * tileInverseScale,
            (tmp.y - tileOrigin.y) * tileInverseScale,
             0
        };
    };

    // Parse topology and transform
    auto topology = TopoJson::getTopology(document, projFn);

    // Parse each TopoJson object as a data layer
    auto objectsIt = document.FindMember("objects");
    if (objectsIt == document.MemberEnd()) { return tileData; }
    auto& objects = objectsIt->value;
    for (auto layer = objects.MemberBegin(); layer != objects.MemberEnd(); ++layer) {
        tileData->layers.push_back(TopoJson::getLayer(layer, topology, m_id));
    }

    // Discard JSON object and return TileData
    return tileData;

}
Exemplo n.º 2
0
Tile::Tile(TileID _id, const MapProjection& _projection, const DataSource* _source) :
    m_id(_id),
    m_projection(&_projection),
    m_sourceId(_source ? _source->id() : 0),
    m_sourceGeneration(_source ? _source->generation() : 0) {

    BoundingBox bounds(_projection.TileBounds(_id));

    m_scale = bounds.width();
    m_inverseScale = 1.0/m_scale;

    updateTileOrigin(_id.wrap);

    // Init model matrix to size of tile
    m_modelMatrix = glm::scale(glm::mat4(1.0), glm::vec3(m_scale));
}
Exemplo n.º 3
0
MapTile::MapTile(TileID _id, const MapProjection& _projection) : m_id(_id),  m_projection(&_projection) {

    glm::dvec4 bounds = _projection.TileBounds(_id); // [x: xmin, y: ymin, z: xmax, w: ymax]
    
    m_scale = 0.5 * glm::abs(bounds.x - bounds.z);
    m_inverseScale = 1.0/m_scale;
    
    // negative y coordinate: to change from y down to y up (tile system has y down and gl context we use has y up).
    m_tileOrigin = glm::dvec2(0.5*(bounds.x + bounds.z), -0.5*(bounds.y + bounds.w));
    
    m_modelMatrix = glm::mat4(1.0);
    
    // Scale model matrix to size of tile
    m_modelMatrix = glm::scale(m_modelMatrix, glm::vec3(m_scale));

}
Exemplo n.º 4
0
Tile::Tile(TileID _id, const MapProjection& _projection) :
    m_id(_id),
    m_projection(&_projection),
    m_visible(false),
    m_priority(0) {

    BoundingBox bounds(_projection.TileBounds(_id));

    m_scale = 0.5 * bounds.width();
    m_inverseScale = 1.0/m_scale;

    m_tileOrigin = bounds.center();
    // negative y coordinate: to change from y down to y up (tile system has y down and gl context we use has y up).
    m_tileOrigin.y *= -1.0;

    // Init model matrix to size of tile
    m_modelMatrix = glm::scale(glm::mat4(1.0), glm::vec3(m_scale));
}
void
UserDefinedScaleFeature::draw( const MapProjection& matrix,
                               isab::MapPlotter& plotter,
                               uint32 textColor )
{
   if ( ! isVisible() ) {
      return;
   }
   MC2BoundingBox bbox = matrix.getBoundingBox();
   // Shamelessly copied from GDImageDraw
   MC2Point screenSize = matrix.getScreenSize();
   uint16 width  = screenSize.getX();
   uint16 height = screenSize.getY();
   
   const float32 scalePartOfWidth = 0.40;
   int bottomMargin = 8;
   int sideMargin = 8;
   int barWidth = 5;
   int textMargin = 2;
   float32 fontSize = 10.0;
   if ( width > 250 ) { // > 250 pxl
      fontSize = 10.0;
      bottomMargin = sideMargin = 6;
   } else if ( width > 150 ) { // 250-151 pxl
      fontSize = 8.0;
      bottomMargin = sideMargin = 4;
      barWidth = 4;
   } else { // less than 150 pxl
      fontSize = 6.0;
      bottomMargin = sideMargin = 2;
      textMargin = 1;
      barWidth = 3;
   }

   int rightPosX = width - sideMargin;
   int posY = height - bottomMargin;
   int leftPosX = int( rint( rightPosX - scalePartOfWidth*width ) );
   float32 xFactor = 0;
   float32 yFactor = 0;
   makeDrawItemParameters( width, height,
                           bbox, xFactor, yFactor );
   
   int32 rightLon = getLon( rightPosX, bbox, xFactor, width );
   int32 leftLon = getLon( leftPosX, bbox, xFactor, width );

   int32 distance = int32( (rightPosX - leftPosX ) * matrix.getPixelScale() *
                           bbox.getCosLat() );

   // Get unit from unit vector.
   int unitIdx;
   distance = chooseFactor( distance, unitIdx );
      
//  int32( rint( ( (rightLon - leftLon)*
//                                     GfxConstants::MC2SCALE_TO_METER*
//                                   bbox.getCosLat() ) ) );
   char distStr[128];
   uint32 white = 0xffffff;
   uint32 black = 0x000000;

   //** Make distance nice length
   // First number zeros
   int32 logDist = 10;
   while( distance > logDist ) {
      logDist *= 10;
   }
   logDist /= 10;
   // Then some fine tuning
   int32 niceDist = 0;
   // Should be even ^2 but 1 is allowed too
   if ( 2*logDist < distance ) {
      niceDist = 2*logDist;
   } else {
      niceDist = logDist;
   }
   while ( niceDist + 2*logDist < distance ) {
      niceDist += 2*logDist;
   }

   //** Nice distance as string
   distStr[ 0 ] = '\0';
   sprintf(distStr, "%u %s",
           (unsigned int)niceDist,
           (niceDist == 1) ?
           m_scaleSettings.getUnitVector()[unitIdx].m_name :
           m_scaleSettings.getUnitVector()[unitIdx].m_pluralName );
      

   // Convert the nice distance back to meters
   niceDist = int32(
      niceDist *
      m_scaleSettings.getUnitVector()[unitIdx].m_factorFromMeters );
   
      
   //** Update leftLon and leftPosX for new nice distance
   leftLon = (rightLon - int32 ( rint( 
      niceDist*GfxConstants::METER_TO_MC2SCALE / bbox.getCosLat() ) ) );

   // Move the stuff to the correct position
   if ( m_point != MC2Point( -1, -1 ) ) {
      rightPosX = m_point.getX();
      posY      = m_point.getY();
   }
   leftPosX = rightPosX - int32( niceDist / matrix.getPixelScale() );

   
   
   
   //** Draw scalebar with four parts
   float32 partWidth = (rightPosX - leftPosX) / 4.0;

   
   
   // Fill all with white
   plotter.setLineWidth( 1 );
   plotter.setPenColor( white );
   plotter.setFillColor( white );
   plotter.drawRect( true, isab::Rectangle( leftPosX,
                                            posY - barWidth,
                                            rightPosX - leftPosX,
                                            barWidth ) );
   
//     gdImageFilledRectangle( m_image, leftPosX, posY - barWidth,
//                             rightPosX, posY, white );
   
   // Black border
   plotter.setPenColor( black );
   plotter.drawRect( false, isab::Rectangle( leftPosX,
                                             posY - barWidth,
                                             rightPosX - leftPosX,
                                             barWidth ) );
//     gdImageRectangle( m_image, leftPosX, posY - barWidth,
//                       rightPosX, posY, white );
   // Leftmost black part
   plotter.setFillColor( black );
   plotter.drawRect( true, isab::Rectangle( leftPosX,
                                            posY - barWidth,
                                            int( rint( partWidth ) ), 
                                            barWidth ) );
   
//     gdImageFilledRectangle( m_image, leftPosX, posY - barWidth,
//                             leftPosX + int( rint( partWidth ) ), 
//                             posY, black );
   // Second black part
   plotter.setFillColor( black );
   {
      int x = leftPosX + int( rint( 2*partWidth ) );
      plotter.drawRect(
         true,
         isab::Rectangle(x,
                         posY - barWidth,
                         leftPosX + int( rint( 3*partWidth ) ) - x,
                         barWidth ) );
   }
   
//     gdImageFilledRectangle( m_image, 
//                             leftPosX + int( rint( 2*partWidth ) ), 
//                             posY - barWidth,
//                             leftPosX + int( rint( 3*partWidth ) ), 
//                             posY, black );

   int barTextSpacing = 2;
   bool textBox = false;

   //** Draw distance string in own square text box
//     char font[512];
//     getFontPath( font, fontName );
//   int textArea[ 8 ];

   // Set the font
   {
      STRING* plotterFont = plotter.createString( m_fontName );   
      plotter.setFont( *plotterFont, m_fontSize );
      plotter.deleteString( plotterFont );
   }

   // Get size of distStr
//     char* err = gdImageStringFT( NULL, textArea, black, font,
//                                  fontSize, 0.0, leftPosX, posY, distStr );
   STRING* str = plotter.createString( distStr );
   isab::Rectangle strRect =
      plotter.getStringAsRectangle( *str, MC2Point(0,0) );
   
   // Use textArea for textbox
//     int textWidth = textArea[ 4 ] - textArea[ 6 ];
//     int textHeight = textArea[ 1 ] - textArea[ 7 ];
   int textWidth = strRect.getWidth();
   int textHeight = strRect.getHeight();
   
   // Put textbox right aligned over scale
   //int textXCenter = rightPosX - int( rint( 2*partWidth ) );
   int textXCenter = rightPosX - (textWidth >> 1);
   int textYBottom = posY - barWidth - barTextSpacing - textMargin;
   // Make sure that text fits in image
   if ( textXCenter + textWidth/2 + textMargin + sideMargin >= width ) {
      textXCenter = width - textWidth/2 - textMargin - sideMargin;
   }
   
   if ( textBox ) {
      plotter.setFillColor( white );
      plotter.drawRect(
         true,
         isab::Rectangle( (textXCenter - textWidth/2 - textMargin ),
                          (textYBottom - textHeight - textMargin),
                          textMargin << 1,
                          textMargin << 1 ) );
//        gdImageFilledRectangle( m_image, 
//                                (textXCenter - textWidth/2 - textMargin ),
//                                (textYBottom - textHeight - textMargin),
//                                (textXCenter + textWidth/2 + textMargin),
//                                (textYBottom + textMargin), 
//                                white );
   }
   
//     int x = textXCenter - textWidth/2;
//     int y = textYBottom;
   int x = textXCenter;
   int y = textYBottom - (textHeight >> 1);
   // Finally draw distStr
   plotter.setPenColor( textColor );
   plotter.drawText( *str, MC2Point( x, y) );
//     gdImageStringFT( m_image, textArea, black, font,
//                      fontSize, 0.0, x, y, distStr );
   plotter.deleteString( str );
}