Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    if (sourceCs->isEqual(*this))
        return crdSource;
    LatLon ll = sourceCs->coord2latlon(crdSource);
    if ( ll.isValid()) {
        return latlon2coord(ll);
    }
    return Coordinate();
}
SPFeatureI FeatureCoverage::newFeatureFrom(const SPFeatureI& existingFeature, const ICoordinateSystem& csySource) {
    Locker<> lock(_mutex);

    auto transform = [&](const UPGeometry& geom)->geos::geom::Geometry * {
        if ( geom.get() == 0)
            return 0;

        geos::geom::Geometry *newgeom = geom->clone();
        if ( csySource.isValid() && !csySource->isEqual(coordinateSystem().ptr())){
            CsyTransform trans(csySource, coordinateSystem());
            newgeom->apply_rw(&trans);
            newgeom->geometryChangedAction();
        }
        GeometryHelper::setCoordinateSystem(newgeom, coordinateSystem().ptr());

        return newgeom;
    };
    if (!connector()->dataIsLoaded()) {
        connector()->loadData(this);
    }
    auto *newfeature = createNewFeature(existingFeature->geometryType());
    const UPGeometry& geom = existingFeature->geometry();
    newfeature->geometry(transform(geom)) ;

    auto variantIndexes = _attributeDefinition.indexes();
    for(auto index : variantIndexes){
        const auto& variant = existingFeature[index];
        auto *variantFeature = createNewFeature(variant->geometryType());
        const auto& geom = variant->geometry();
        variantFeature->geometry(transform(geom)) ;
        newfeature->setSubFeature(index, variantFeature);


    }
    _features.push_back(newfeature);
    return _features.back();
}