Ejemplo n.º 1
0
void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader)
{
    ASSERT_UNUSED(loader, m_loader == loader);

    Vector<RefPtr<TextTrackRegion> > newRegions;
    m_loader->getNewRegions(newRegions);

    for (size_t i = 0; i < newRegions.size(); ++i) {
        newRegions[i]->setTrack(this);
        regionList()->add(newRegions[i]);
    }
}
Ejemplo n.º 2
0
std::vector< std::shared_ptr<Carta::Lib::RegionInfo> >
RegionCASA::_loadRegion( const QString & fname, std::shared_ptr<Carta::Lib::Image::ImageInterface> imagePtr ){
    std::vector<std::shared_ptr<Carta::Lib::RegionInfo> > regionInfos;

    casa::String fileName( fname.toStdString().c_str() );
    CCImageBase * base = dynamic_cast<CCImageBase*>( imagePtr.get() );
    if ( base ){
        Carta::Lib::Image::MetaDataInterface::SharedPtr metaPtr = base->metaData();
        CCMetaDataInterface* metaData = dynamic_cast<CCMetaDataInterface*>(metaPtr.get());
        if ( metaData ){
            std::shared_ptr<casa::CoordinateSystem> cs = metaData->getCoordinateSystem();
            std::vector < int > dimensions = imagePtr->dims();
            int dimCount = dimensions.size();
            casa::IPosition shape(dimCount);
            for ( int i = 0; i < dimCount; i++ ){
                shape[i] = dimensions[i];
            }
            casa::RegionTextList regionList( fileName, *cs.get(), shape );
            casa::Vector<casa::AsciiAnnotationFileLine> aaregions = regionList.getLines();
            int regionCount = aaregions.size();
            for ( int i = 0; i < regionCount; i++ ){
                if ( aaregions[i].getType() != casa::AsciiAnnotationFileLine::ANNOTATION ){
                    continue;
                }
                casa::CountedPtr<const casa::AnnotationBase> ann = aaregions[i].getAnnotationBase();
                std::shared_ptr<Carta::Lib::RegionInfo> rInfo( new Carta::Lib::RegionInfo());

                casa::Vector<casa::MDirection> directions = ann->getConvertedDirections();
                casa::AnnotationBase::Direction points = ann->getDirections();
                std::vector<std::pair<double,double> > corners =
                            _getPixelVertices( points, *cs.get(), directions );
                int annType = ann->getType();
                switch( annType ){
                case casa::AnnotationBase::RECT_BOX : {
                    _addCorners( rInfo, corners );
                    rInfo->setRegionType( Carta::Lib::RegionInfo::RegionType::Polygon );
                }
                break;
                case casa::AnnotationBase::ELLIPSE : {
                    rInfo->setRegionType( Carta::Lib::RegionInfo::RegionType::Ellipse );
                    const casa::AnnEllipse* ellipse = dynamic_cast<const casa::AnnEllipse*>( ann.get() );
                    casa::Int directionIndex = cs->findCoordinate(casa::Coordinate::Type::DIRECTION );

                    casa::MDirection::Types csType = casa::MDirection::EXTRA;
                    if ( directionIndex >= 0 ){
                        casa::DirectionCoordinate  dCoord = cs->directionCoordinate(directionIndex);
                        csType = dCoord.directionType();
                    }

                    if ( csType == casa::MDirection::EXTRA ){
                        qWarning( "Unable to complete elliptical region, unspecified direction type.");
                        continue;
                    }

                    // convert to the viewer's world coordinates... <mdirection>
                    casa::MDirection dir_center = casa::MDirection::Convert(ellipse->getCenter( ), csType)();
                    casa::Vector<double> center = dir_center.getAngle("rad").getValue( );
                    // 90 deg around 0 & 180 deg
                    const double major_radius = ellipse->getSemiMajorAxis().getValue("rad");
                    const double minor_radius = ellipse->getSemiMinorAxis().getValue("rad");
                    const double pos_angle = ellipse->getPositionAngle( ).getValue("deg");
                    const bool x_is_major = ((pos_angle > 45.0 && pos_angle < 135.0) ||
                            (pos_angle > 225.0 && pos_angle < 315.0));
                    const double xradius = (x_is_major ? major_radius : minor_radius);
                    const double yradius = (x_is_major ? minor_radius : major_radius);

                    casa::Vector<casa::Double> world0(2, 0);
                    casa::Vector<casa::Double> world1(2, 0);
                    world0[0] = center[0] - xradius;
                    world0[1] = center[1] - yradius;
                    world1[0] = center[0] + xradius;
                    world1[1] = center[1] + yradius;
                    casa::Vector<casa::Double> pixel0(2, 0);
                    casa::Vector<casa::Double> pixel1(2, 0);
                    std::vector<std::pair<double,double> > ellipseCorners(2);

                    const casa::CoordinateSystem ellipsCoord = ellipse->getCsys();
                    bool firstConvert = ellipsCoord.directionCoordinate().toPixel( pixel0, world0 );
                    bool secondConvert = ellipsCoord.directionCoordinate().toPixel( pixel1, world1 );
                    if ( firstConvert && secondConvert ){
                        ellipseCorners[0] = std::pair<double,double>( pixel0[0], pixel0[1] );
                        ellipseCorners[1] = std::pair<double,double>( pixel1[0], pixel1[1] );
                        _addCorners( rInfo, ellipseCorners );
                    }
                    else {
                        qDebug() << "Problem storing ellipse corners: "<<ellipsCoord.errorMessage().c_str();
                    }
                }
                break;
                case casa::AnnotationBase::POLYGON : {
                    _addCorners( rInfo, corners );
                    rInfo->setRegionType( Carta::Lib::RegionInfo::RegionType::Polygon );
                }
                break;
                //Point????
                case casa::AnnotationBase::SYMBOL : {
                    _addCorners( rInfo, corners );
                    rInfo->setRegionType( Carta::Lib::RegionInfo::RegionType::Polygon );
                }
                break;
                }
                regionInfos.push_back( rInfo );

            }
        }
    }
    return regionInfos;
}
Ejemplo n.º 3
0
/*
 * Initializes the region data from the ICU resource bundles.  The region data
 * contains the basic relationships such as which regions are known, what the numeric
 * codes are, any known aliases, and the territory containment data.
 *
 * If the region data has already loaded, then this method simply returns without doing
 * anything meaningful.
 */
void Region::loadRegionData(UErrorCode &status) {

    // Construct service objs first
    LocalUHashtablePointer newRegionIDMap(uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status));
    LocalUHashtablePointer newNumericCodeMap(uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status));
    LocalUHashtablePointer newRegionAliases(uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status));
    LocalPointer<DecimalFormat> df(new DecimalFormat(status), status);

    LocalPointer<UVector> continents(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
    LocalPointer<UVector> groupings(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
    allRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);

    LocalUResourceBundlePointer metadata(ures_openDirect(NULL,"metadata",&status));
    LocalUResourceBundlePointer metadataAlias(ures_getByKey(metadata.getAlias(),"alias",NULL,&status));
    LocalUResourceBundlePointer territoryAlias(ures_getByKey(metadataAlias.getAlias(),"territory",NULL,&status));

    LocalUResourceBundlePointer supplementalData(ures_openDirect(NULL,"supplementalData",&status));
    LocalUResourceBundlePointer codeMappings(ures_getByKey(supplementalData.getAlias(),"codeMappings",NULL,&status));

    LocalUResourceBundlePointer idValidity(ures_getByKey(supplementalData.getAlias(),"idValidity",NULL,&status));
    LocalUResourceBundlePointer regionList(ures_getByKey(idValidity.getAlias(),"region",NULL,&status));
    LocalUResourceBundlePointer regionRegular(ures_getByKey(regionList.getAlias(),"regular",NULL,&status));
    LocalUResourceBundlePointer regionMacro(ures_getByKey(regionList.getAlias(),"macroregion",NULL,&status));
    LocalUResourceBundlePointer regionUnknown(ures_getByKey(regionList.getAlias(),"unknown",NULL,&status));

    LocalUResourceBundlePointer territoryContainment(ures_getByKey(supplementalData.getAlias(),"territoryContainment",NULL,&status));
    LocalUResourceBundlePointer worldContainment(ures_getByKey(territoryContainment.getAlias(),"001",NULL,&status));
    LocalUResourceBundlePointer groupingContainment(ures_getByKey(territoryContainment.getAlias(),"grouping",NULL,&status));

    if (U_FAILURE(status)) {
        return;
    }

    // now, initialize
    df->setParseIntegerOnly(TRUE);
    uhash_setValueDeleter(newRegionIDMap.getAlias(), deleteRegion);  // regionIDMap owns objs
    uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // regionAliases owns the string keys


    while ( ures_hasNext(regionRegular.getAlias()) ) {
        UnicodeString regionName = ures_getNextUnicodeString(regionRegular.getAlias(),NULL,&status);
        int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
        UChar buf[6];
        regionName.extract(buf,6,status);
        if ( rangeMarkerLocation > 0 ) {
            UChar endRange = regionName.charAt(rangeMarkerLocation+1);
            buf[rangeMarkerLocation] = 0;
            while ( buf[rangeMarkerLocation-1] <= endRange ) {
                LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), status);
                allRegions->addElement(newRegion.orphan(),status);
                buf[rangeMarkerLocation-1]++;
            }
        } else {
            LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
            allRegions->addElement(newRegion.orphan(),status);
        }
    }

    while ( ures_hasNext(regionMacro.getAlias()) ) {
        UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlias(),NULL,&status);
        int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER);
        UChar buf[6];
        regionName.extract(buf,6,status);
        if ( rangeMarkerLocation > 0 ) {
            UChar endRange = regionName.charAt(rangeMarkerLocation+1);
            buf[rangeMarkerLocation] = 0;
            while ( buf[rangeMarkerLocation-1] <= endRange ) {
                LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), status);
                allRegions->addElement(newRegion.orphan(),status);
                buf[rangeMarkerLocation-1]++;
            }
        } else {
            LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
            allRegions->addElement(newRegion.orphan(),status);
        }
    }

    while ( ures_hasNext(regionUnknown.getAlias()) ) {
        LocalPointer<UnicodeString> regionName (new UnicodeString(ures_getNextUnicodeString(regionUnknown.getAlias(),NULL,&status),status));
        allRegions->addElement(regionName.orphan(),status);
    }

    while ( ures_hasNext(worldContainment.getAlias()) ) {
        UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeString(worldContainment.getAlias(),NULL,&status));
        continents->addElement(continentName,status);
    }

    while ( ures_hasNext(groupingContainment.getAlias()) ) {
        UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeString(groupingContainment.getAlias(),NULL,&status));
        groupings->addElement(groupingName,status);
    }

    for ( int32_t i = 0 ; i < allRegions->size() ; i++ ) {
        LocalPointer<Region> r(new Region(), status);
        if ( U_FAILURE(status) ) {
           return;
        }
        UnicodeString *regionName = (UnicodeString *)allRegions->elementAt(i);
        r->idStr = *regionName;

        r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV);
        r->type = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known.

        Formattable result;
        UErrorCode ps = U_ZERO_ERROR;
        df->parse(r->idStr,result,ps);
        if ( U_SUCCESS(ps) ) {
            r->code = result.getLong(); // Convert string to number
            uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)(r.getAlias()),&status);
            r->type = URGN_SUBCONTINENT;
        } else {
            r->code = -1;
        }
        void* idStrAlias = (void*)&(r->idStr); // about to orphan 'r'. Save this off.
        uhash_put(newRegionIDMap.getAlias(),idStrAlias,(void *)(r.orphan()),&status); // regionIDMap takes ownership
    }

    // Process the territory aliases
    while ( ures_hasNext(territoryAlias.getAlias()) ) {
        LocalUResourceBundlePointer res(ures_getNextResource(territoryAlias.getAlias(),NULL,&status));
        const char *aliasFrom = ures_getKey(res.getAlias());
        LocalPointer<UnicodeString> aliasFromStr(new UnicodeString(aliasFrom, -1, US_INV), status);
        UnicodeString aliasTo = ures_getUnicodeStringByKey(res.getAlias(),"replacement",&status);
        res.adoptInstead(NULL);

        const Region *aliasToRegion = (Region *) uhash_get(newRegionIDMap.getAlias(),&aliasTo);
        Region *aliasFromRegion = (Region *)uhash_get(newRegionIDMap.getAlias(),aliasFromStr.getAlias());

        if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is just an alias from some string to a region
            uhash_put(newRegionAliases.getAlias(),(void *)aliasFromStr.orphan(), (void *)aliasToRegion,&status);
        } else {
            if ( aliasFromRegion == NULL ) { // Deprecated region code not in the master codes list - so need to create a deprecated region for it.
                LocalPointer<Region> newRgn(new Region, status); 
                if ( U_SUCCESS(status) ) {
                    aliasFromRegion = newRgn.orphan();
                } else {
                    return; // error out
                }
                aliasFromRegion->idStr.setTo(*aliasFromStr);
                aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length(),aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV);
                uhash_put(newRegionIDMap.getAlias(),(void *)&(aliasFromRegion->idStr),(void *)aliasFromRegion,&status);
                Formattable result;
                UErrorCode ps = U_ZERO_ERROR;
                df->parse(aliasFromRegion->idStr,result,ps);
                if ( U_SUCCESS(ps) ) {
                    aliasFromRegion->code = result.getLong(); // Convert string to number
                    uhash_iput(newNumericCodeMap.getAlias(),aliasFromRegion->code,(void *)aliasFromRegion,&status);
                } else {
                    aliasFromRegion->code = -1;
                }
                aliasFromRegion->type = URGN_DEPRECATED;
            } else {
                aliasFromRegion->type = URGN_DEPRECATED;
            }

            {
                LocalPointer<UVector> newPreferredValues(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
                aliasFromRegion->preferredValues = newPreferredValues.orphan();
            }
            if( U_FAILURE(status)) {
                return;
            }
            UnicodeString currentRegion;
            //currentRegion.remove();   TODO: was already 0 length?
            for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) {
                if ( aliasTo.charAt(i) != 0x0020 ) {
                    currentRegion.append(aliasTo.charAt(i));
                }
                if ( aliasTo.charAt(i) == 0x0020 || i+1 == aliasTo.length() ) {
                    Region *target = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&currentRegion);
                    if (target) {
                        LocalPointer<UnicodeString> preferredValue(new UnicodeString(target->idStr), status);
                        aliasFromRegion->preferredValues->addElement((void *)preferredValue.orphan(),status);  // may add null if err
                    }
                    currentRegion.remove();
                }
            }
        }
    }

    // Process the code mappings - This will allow us to assign numeric codes to most of the territories.
    while ( ures_hasNext(codeMappings.getAlias()) ) {
        UResourceBundle *mapping = ures_getNextResource(codeMappings.getAlias(),NULL,&status);
        if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) {
            UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0,&status);
            UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mapping,1,&status);
            UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapping,2,&status);

            Region *r = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&codeMappingID);
            if ( r ) {
                Formattable result;
                UErrorCode ps = U_ZERO_ERROR;
                df->parse(codeMappingNumber,result,ps);
                if ( U_SUCCESS(ps) ) {
                    r->code = result.getLong(); // Convert string to number
                    uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)r,&status);
                }
                LocalPointer<UnicodeString> code3(new UnicodeString(codeMapping3Letter), status);
                uhash_put(newRegionAliases.getAlias(),(void *)code3.orphan(), (void *)r,&status);
            }
        }
        ures_close(mapping);
    }

    // Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPINGS
    Region *r;
    UnicodeString WORLD_ID_STRING(WORLD_ID);
    r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&WORLD_ID_STRING);
    if ( r ) {
        r->type = URGN_WORLD;
    }

    UnicodeString UNKNOWN_REGION_ID_STRING(UNKNOWN_REGION_ID);
    r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&UNKNOWN_REGION_ID_STRING);
    if ( r ) {
        r->type = URGN_UNKNOWN;
    }

    for ( int32_t i = 0 ; i < continents->size() ; i++ ) {
        r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)continents->elementAt(i));
        if ( r ) {
            r->type = URGN_CONTINENT;
        }
    }

    for ( int32_t i = 0 ; i < groupings->size() ; i++ ) {
        r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)groupings->elementAt(i));
        if ( r ) {
            r->type = URGN_GROUPING;
        }
    }

    // Special case: The region code "QO" (Outlying Oceania) is a subcontinent code added by CLDR
    // even though it looks like a territory code.  Need to handle it here.

    UnicodeString OUTLYING_OCEANIA_REGION_ID_STRING(OUTLYING_OCEANIA_REGION_ID);
    r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&OUTLYING_OCEANIA_REGION_ID_STRING);
    if ( r ) {
        r->type = URGN_SUBCONTINENT;
    }

    // Load territory containment info from the supplemental data.
    while ( ures_hasNext(territoryContainment.getAlias()) ) {
        LocalUResourceBundlePointer mapping(ures_getNextResource(territoryContainment.getAlias(),NULL,&status));
        if( U_FAILURE(status) ) {
            return;  // error out
        }
        const char *parent = ures_getKey(mapping.getAlias());
        if (uprv_strcmp(parent, "containedGroupings") == 0 || uprv_strcmp(parent, "deprecated") == 0) {
            continue; // handle new pseudo-parent types added in ICU data per cldrbug 7808; for now just skip.
            // #11232 is to do something useful with these.
        }
        UnicodeString parentStr = UnicodeString(parent, -1 , US_INV);
        Region *parentRegion = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&parentStr);

        for ( int j = 0 ; j < ures_getSize(mapping.getAlias()); j++ ) {
            UnicodeString child = ures_getUnicodeStringByIndex(mapping.getAlias(),j,&status);
            Region *childRegion = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&child);
            if ( parentRegion != NULL && childRegion != NULL ) {

                // Add the child region to the set of regions contained by the parent
                if (parentRegion->containedRegions == NULL) {
                    parentRegion->containedRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
                }

                LocalPointer<UnicodeString> childStr(new UnicodeString(), status);
                if( U_FAILURE(status) ) {
                    return;  // error out
                }
                childStr->fastCopyFrom(childRegion->idStr);
                parentRegion->containedRegions->addElement((void *)childStr.orphan(),status);

                // Set the parent region to be the containing region of the child.
                // Regions of type GROUPING can't be set as the parent, since another region
                // such as a SUBCONTINENT, CONTINENT, or WORLD must always be the parent.
                if ( parentRegion->type != URGN_GROUPING) {
                    childRegion->containingRegion = parentRegion;
                }
            }
        }
    }

    // Create the availableRegions lists
    int32_t pos = UHASH_FIRST;
    while ( const UHashElement* element = uhash_nextElement(newRegionIDMap.getAlias(),&pos)) {
        Region *ar = (Region *)element->value.pointer;
        if ( availableRegions[ar->type] == NULL ) {
            LocalPointer<UVector> newAr(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status);
            availableRegions[ar->type] = newAr.orphan();
        }
        LocalPointer<UnicodeString> arString(new UnicodeString(ar->idStr), status);
        if( U_FAILURE(status) ) {
            return;  // error out
        }
        availableRegions[ar->type]->addElement((void *)arString.orphan(),status);
    }
    
    ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup);
    // copy hashtables
    numericCodeMap = newNumericCodeMap.orphan();
    regionIDMap = newRegionIDMap.orphan();
    regionAliases = newRegionAliases.orphan();
}