Пример #1
0
        public static void WriteParamData(EpsgData data, BinaryWriter writerText, Func <ushort, BinaryWriter> paramFileGenerator)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.ParamTextValues.DistinctNonEmptyStrings()
                                                   );

            foreach (var coordinateOpMethod in data.Repository.CoordinateOperationMethods)
            {
                var usedBy = coordinateOpMethod.UsedBy.OrderBy(x => x.Code).ToList();

                using (var writerData = paramFileGenerator((ushort)coordinateOpMethod.Code)) {
                    var paramUses = coordinateOpMethod.ParamUse.OrderBy(x => x.SortOrder).ToList();
                    writerData.Write((byte)paramUses.Count);
                    foreach (var paramUse in paramUses)
                    {
                        writerData.Write((ushort)paramUse.Parameter.Code);
                        writerData.Write((byte)(paramUse.SignReversal.GetValueOrDefault() ? 0x01 : 0x02));
                    }
                    writerData.Write((ushort)usedBy.Count);
                    foreach (var coordinateOperation in usedBy)
                    {
                        writerData.Write((ushort)coordinateOperation.Code);
                        var paramValues = coordinateOperation.ParameterValues.ToList();
                        foreach (var paramUse in paramUses)
                        {
                            var paramCode  = paramUse.Parameter.Code;
                            var paramValue = paramValues.SingleOrDefault(x => x.Parameter.Code == paramCode);

                            // the value
                            if (null != paramValue && paramValue.NumericValue.HasValue)
                            {
                                writerData.Write((ushort)data.GetNumberIndex(paramValue.NumericValue.Value));
                            }
                            else if (null != paramValue && !String.IsNullOrWhiteSpace(paramValue.TextValue))
                            {
                                writerData.Write((ushort)(stringLookUp[paramValue.TextValue] | 0x8000));
                            }
                            else
                            {
                                writerData.Write((ushort)0xffff);
                            }

                            // the uom of the value
                            if (null != paramValue && null != paramValue.Uom)
                            {
                                writerData.Write((ushort)paramValue.Uom.Code);
                            }
                            else
                            {
                                writerData.Write((ushort)0xffff);
                            }
                        }
                    }

                    writerData.Flush();
                }
            }
        }
Пример #2
0
        public static void WriteAreas(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var areas = data.Repository.Areas.ToList();

            var stringLookUp = WriteTextDictionary(data, textWriter,
                areas.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            var isos = new List<EpsgArea>();

            dataWriter.Write((ushort)areas.Count);
            foreach (var area in areas) {
                dataWriter.Write((ushort)area.Code);

                var encodedWestBound = EncodeDegreeValueToShort(area.WestBound);
                var encodedEastBound = EncodeDegreeValueToShort(area.EastBound);
                var encodedSouthBound =EncodeDegreeValueToShort(area.SouthBound);
                var encodedNorthBound =EncodeDegreeValueToShort(area.NorthBound);

            // ReSharper disable CompareOfFloatsByEqualityOperator
                if (DecodeDegreeValueFromShort(encodedWestBound) != (area.WestBound ?? 0))
                    throw new InvalidOperationException();
                if (DecodeDegreeValueFromShort(encodedEastBound) != (area.EastBound ?? 0))
                    throw new InvalidOperationException();
                if (DecodeDegreeValueFromShort(encodedNorthBound) != (area.NorthBound ?? 0))
                    throw new InvalidOperationException();
                if (DecodeDegreeValueFromShort(encodedSouthBound) != (area.SouthBound ?? 0))
                    throw new InvalidOperationException();
            // ReSharper restore CompareOfFloatsByEqualityOperator

                dataWriter.Write(encodedWestBound);
                dataWriter.Write(encodedEastBound);
                dataWriter.Write(encodedSouthBound);
                dataWriter.Write(encodedNorthBound);
                dataWriter.Write((ushort)stringLookUp[area.Name ?? String.Empty]);

                if (String.IsNullOrWhiteSpace(area.Iso2)) {
                    dataWriter.Write((ushort)0);
                }
                else {
                    dataWriter.Write((byte)area.Iso2[0]);
                    dataWriter.Write((byte)area.Iso2[1]);
                }

                if (String.IsNullOrWhiteSpace(area.Iso3)) {
                    dataWriter.Write((ushort)0);
                    dataWriter.Write((byte)0);
                }
                else {
                    dataWriter.Write((byte)area.Iso3[0]);
                    dataWriter.Write((byte)area.Iso3[1]);
                    dataWriter.Write((byte)area.Iso3[2]);
                }

            }
        }
Пример #3
0
        internal static void WriteOpPaths(EpsgData data, BinaryWriter writerOpForward, BinaryWriter writerOpReverse)
        {
            var crsBoundOps       = data.Repository.CrsBoundCoordinateOperations;
            var forwardOpMappings = crsBoundOps.ToLookup(x => x.SourceCrs.Code, x => checked ((ushort)x.Code));

            writerOpForward.Write((ushort)forwardOpMappings.Count);
            var pendingCodes = new List <ushort>();

            foreach (var map in forwardOpMappings.OrderBy(x => x.Key))
            {
                var codes = map.OrderBy(x => x).ToList();
                writerOpForward.Write(checked ((ushort)map.Key));
                writerOpForward.Write(checked ((ushort)codes.Count));
                if (codes.Count == 1)
                {
                    writerOpForward.Write(codes[0]);
                }
                else
                {
                    writerOpForward.Write(checked ((ushort)(pendingCodes.Count)));
                    pendingCodes.AddRange(codes);
                }
            }
            foreach (var c in pendingCodes)
            {
                writerOpForward.Write(c);
            }

            var reverseOpMappings = crsBoundOps.ToLookup(x => x.TargetCrs.Code, x => checked ((ushort)x.Code));

            writerOpReverse.Write((ushort)reverseOpMappings.Count);
            pendingCodes = new List <ushort>();
            foreach (var map in reverseOpMappings.OrderBy(x => x.Key))
            {
                var codes = map.OrderBy(x => x).ToList();
                writerOpReverse.Write(checked ((ushort)map.Key));
                writerOpReverse.Write(checked ((ushort)codes.Count));
                if (codes.Count == 1)
                {
                    writerOpReverse.Write(codes[0]);
                }
                else
                {
                    writerOpReverse.Write(checked ((ushort)(pendingCodes.Count)));
                    pendingCodes.AddRange(codes);
                }
            }
            foreach (var c in pendingCodes)
            {
                writerOpReverse.Write(c);
            }
        }
Пример #4
0
        public static void WriteParameters(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.Parameters.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            int c = data.Repository.Parameters.Count();

            writerData.Write((ushort)c);
            foreach (var parameter in data.Repository.Parameters.OrderBy(x => x.Code))
            {
                writerData.Write((ushort)parameter.Code);
                writerData.Write((ushort)stringLookUp[parameter.Name]);
            }
        }
Пример #5
0
 public static void WriteNumberLookUps(EpsgData data, BinaryWriter writerDouble, BinaryWriter writerInt, BinaryWriter writerShort)
 {
     foreach (var number in data.NumberLookUpDouble)
     {
         writerDouble.Write(number);
     }
     foreach (var number in data.NumberLookUpInt)
     {
         writerInt.Write((int)number);
     }
     foreach (var number in data.NumberLookUpShort)
     {
         writerShort.Write((short)number);
     }
 }
Пример #6
0
        public static void WriteOpMethod(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.CoordinateOperationMethods.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            int c = data.Repository.CoordinateOperationMethods.Count();

            writerData.Write((ushort)c);
            foreach (var opMethod in data.Repository.CoordinateOperationMethods.OrderBy(x => x.Code))
            {
                writerData.Write((ushort)opMethod.Code);
                writerData.Write((byte)(opMethod.Reverse ? 'B' : 'U'));
                writerData.Write((ushort)stringLookUp[opMethod.Name]);
            }
        }
Пример #7
0
        private static Dictionary <string, ushort> WriteTextDictionary(EpsgData data, BinaryWriter textWriter, IEnumerable <string> allStrings)
        {
            var stringLookUp = new Dictionary <string, ushort>();
            int textOffset   = 0;

            foreach (var textItem in allStrings)
            {
                var textBytes = data.GenerateWordIndexBytes(textItem);
                textWriter.Write((byte)textBytes.Length);
                textWriter.Write(textBytes);
                stringLookUp.Add(textItem, (ushort)textOffset);
                textOffset += textBytes.Length + sizeof(byte);
            }
            stringLookUp.Add(String.Empty, ushort.MaxValue);
            return(stringLookUp);
        }
Пример #8
0
        public static void WriteDatums(EpsgData data, BinaryWriter engineeringWriter, BinaryWriter verticalWriter, BinaryWriter geodeticWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   data.Repository.Datums.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            foreach (var datumSet in data.Repository.Datums.GroupBy(x => x.Type))
            {
                var datums = datumSet.OrderBy(x => x.Code);
                switch (datumSet.Key.ToUpper())
                {
                case "ENGINEERING":
                    engineeringWriter.Write((ushort)datums.Count());
                    foreach (var datum in datums)
                    {
                        engineeringWriter.Write((ushort)datum.Code);
                        engineeringWriter.Write((ushort)(stringLookUp[datum.Name]));
                        engineeringWriter.Write((ushort)datum.AreaOfUse.Code);
                    }
                    break;

                case "VERTICAL":
                    verticalWriter.Write((ushort)datums.Count());
                    foreach (var datum in datums)
                    {
                        verticalWriter.Write((ushort)datum.Code);
                        verticalWriter.Write((ushort)(stringLookUp[datum.Name]));
                        verticalWriter.Write((ushort)datum.AreaOfUse.Code);
                    }
                    break;

                case "GEODETIC":
                    geodeticWriter.Write((ushort)datums.Count());
                    foreach (var datum in datums)
                    {
                        geodeticWriter.Write((ushort)datum.Code);
                        geodeticWriter.Write((ushort)(stringLookUp[datum.Name]));
                        geodeticWriter.Write((ushort)datum.AreaOfUse.Code);
                        geodeticWriter.Write((ushort)datum.Ellipsoid.Code);
                        geodeticWriter.Write((ushort)datum.PrimeMeridian.Code);
                    }
                    break;

                default: throw new InvalidDataException("Invalid datum type: " + datumSet.Key);
                }
            }
        }
Пример #9
0
        public static void WriteMeridians(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   data.Repository.PrimeMeridians.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            int c = data.Repository.PrimeMeridians.Count();

            dataWriter.Write((ushort)c);
            foreach (var meridian in data.Repository.PrimeMeridians.OrderBy(x => x.Code))
            {
                dataWriter.Write((ushort)meridian.Code);
                dataWriter.Write((ushort)meridian.Uom.Code);
                dataWriter.Write((ushort)data.GetNumberIndex(meridian.GreenwichLon));
                dataWriter.Write((byte)stringLookUp[meridian.Name]);
            }
        }
Пример #10
0
        public static void WriteAxes(EpsgData data, BinaryWriter textWriter, BinaryWriter data1Writer, BinaryWriter data2Writer, BinaryWriter data3Writer)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   data.Repository.Axes.Select(x => x.NameObject.Name).Distinct()
                                                   .Concat(data.Repository.Axes.Select(x => x.Orientation).Distinct())
                                                   .Concat(data.Repository.Axes.Select(x => x.Abbreviation).Distinct())
                                                   .DistinctNonEmptyStrings()
                                                   );

            var axesData = data.Repository.Axes.ToLookup(x => x.CoordinateSystem.Code);

            foreach (var axisFileGroup in axesData.GroupBy(x => x.Count()))
            {
                var          axisCount = axisFileGroup.Key;
                BinaryWriter dataWriter;
                if (axisCount == 1)
                {
                    dataWriter = data1Writer;
                }
                else if (axisCount == 2)
                {
                    dataWriter = data2Writer;
                }
                else if (axisCount == 3)
                {
                    dataWriter = data3Writer;
                }
                else
                {
                    throw new InvalidDataException();
                }

                dataWriter.Write((ushort)axisFileGroup.Count());
                foreach (var axisSet in axisFileGroup.OrderBy(x => x.Key))
                {
                    dataWriter.Write((ushort)axisSet.Key);
                    foreach (var axis in axisSet.OrderBy(x => x.OrderValue))
                    {
                        dataWriter.Write((ushort)axis.Uom.Code);
                        dataWriter.Write((ushort)stringLookUp[axis.Name]);
                        dataWriter.Write((ushort)stringLookUp[axis.Orientation]);
                        dataWriter.Write((ushort)stringLookUp[axis.Abbreviation]);
                    }
                }
            }
        }
Пример #11
0
        public static void WriteEllipsoids(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   data.Repository.Ellipsoids.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            int c = data.Repository.Ellipsoids.Count();

            dataWriter.Write((ushort)c);
            foreach (var ellipsoid in data.Repository.Ellipsoids.OrderBy(x => x.Code))
            {
                dataWriter.Write((ushort)ellipsoid.Code);
                dataWriter.Write((ushort)data.GetNumberIndex(ellipsoid.SemiMajorAxis));
                dataWriter.Write((ushort)data.GetNumberIndex(ellipsoid.InverseFlattening ?? ellipsoid.SemiMinorAxis ?? 0));
                dataWriter.Write((ushort)stringLookUp[ellipsoid.Name]);
                dataWriter.Write((byte)(ellipsoid.Uom.Code - 9000));
            }
        }
Пример #12
0
        public static void WriteCoordinateReferenceSystem(EpsgData data, BinaryWriter writerText, BinaryWriter writerNormal, BinaryWriter writerComposite)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.Crs.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            foreach (var crsGroup in data.Repository.Crs.Select(x => new { KindByte = ToCrsKindByte(x.Kind), Crs = x }).GroupBy(x => x.KindByte == 'C'))
            {
                var crsItemCount     = crsGroup.Count();
                var crsItems         = crsGroup.OrderBy(x => x.Crs.Code);
                var groupIsComposite = crsGroup.Key;
                if (groupIsComposite)
                {
                    writerComposite.Write((ushort)crsItemCount);
                    foreach (var crs in crsItems.Select(x => x.Crs))
                    {
                        writerComposite.Write((ushort)crs.Code);
                        writerComposite.Write((ushort)crs.CompoundHorizontalCrs.Code);
                        writerComposite.Write((ushort)crs.CompoundVerticalCrs.Code);
                        writerComposite.Write((ushort)crs.Area.Code);
                        writerComposite.Write((ushort)stringLookUp[crs.Name]);
                        writerComposite.Write((byte)(crs.Deprecated ? 0xff : 0));
                    }
                }
                else
                {
                    writerNormal.Write((ushort)crsItemCount);
                    foreach (var crsData in crsItems)
                    {
                        var crs = crsData.Crs;
                        writerNormal.Write((uint)crs.Code);
                        var datum = GetFirstDatum(crs);
                        writerNormal.Write((ushort)(null == datum ? 0 : datum.Code));
                        writerNormal.Write((ushort)(crs.SourceGeographicCrs == null ? 0 : crs.SourceGeographicCrs.Code));
                        writerNormal.Write((ushort)(crs.Projection == null ? 0 : crs.Projection.Code));
                        writerNormal.Write((ushort)crs.CoordinateSystem.Code);
                        writerNormal.Write((ushort)crs.Area.Code);
                        writerNormal.Write((ushort)stringLookUp[crs.Name]);
                        writerNormal.Write((byte)(crs.Deprecated ? 0xff : 0));
                        writerNormal.Write((byte)crsData.KindByte);
                    }
                }
            }
        }
Пример #13
0
        public static void WriteUnitOfMeasures(EpsgData data, BinaryWriter lengthWriter, BinaryWriter angleWriter, BinaryWriter scaleWriter, BinaryWriter timeWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   data.Repository.Uoms.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            var uomGroups = data.Repository.Uoms.GroupBy(x => x.Type.ToUpper());

            foreach (var uomGroup in uomGroups)
            {
                BinaryWriter writer;
                if (uomGroup.Key == "LENGTH")
                {
                    writer = lengthWriter;
                }
                else if (uomGroup.Key == "ANGLE")
                {
                    writer = angleWriter;
                }
                else if (uomGroup.Key == "SCALE")
                {
                    writer = scaleWriter;
                }
                else if (uomGroup.Key == "TIME")
                {
                    writer = timeWriter;
                }
                else
                {
                    throw new InvalidDataException("Invalid uom type: " + uomGroup.Key);
                }

                writer.Write((ushort)uomGroup.Count());
                foreach (var uom in uomGroup.OrderBy(x => x.Code))
                {
                    writer.Write((ushort)uom.Code);
                    writer.Write((ushort)stringLookUp[uom.Name]);
                    writer.Write((ushort)data.GetNumberIndex(uom.FactorB ?? 0));
                    writer.Write((ushort)data.GetNumberIndex(uom.FactorC ?? 0));
                }
            }
        }
Пример #14
0
        public static void WriteAxes(EpsgData data, BinaryWriter textWriter, BinaryWriter data1Writer, BinaryWriter data2Writer, BinaryWriter data3Writer)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                data.Repository.Axes.Select(x => x.NameObject.Name).Distinct()
                .Concat(data.Repository.Axes.Select(x => x.Orientation).Distinct())
                .Concat(data.Repository.Axes.Select(x => x.Abbreviation).Distinct())
                .DistinctNonEmptyStrings()
            );

            var axesData = data.Repository.Axes.ToLookup(x => x.CoordinateSystem.Code);

            foreach(var axisFileGroup in axesData.GroupBy(x => x.Count())){
                var axisCount = axisFileGroup.Key;
                BinaryWriter dataWriter;
                if (axisCount == 1)
                    dataWriter = data1Writer;
                else if (axisCount == 2)
                    dataWriter = data2Writer;
                else if (axisCount == 3)
                    dataWriter = data3Writer;
                else
                    throw new InvalidDataException();

                dataWriter.Write((ushort)axisFileGroup.Count());
                foreach (var axisSet in axisFileGroup.OrderBy(x => x.Key)) {
                    dataWriter.Write((ushort)axisSet.Key);
                    foreach (var axis in axisSet.OrderBy(x => x.OrderValue)) {
                        dataWriter.Write((ushort)axis.Uom.Code);
                        dataWriter.Write((ushort)stringLookUp[axis.Name]);
                        dataWriter.Write((ushort)stringLookUp[axis.Orientation]);
                        dataWriter.Write((ushort)stringLookUp[axis.Abbreviation]);
                    }
                }

            }
        }
Пример #15
0
        public static void WriteCoordinateSystems(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.CoordinateSystems.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            int c = data.Repository.CoordinateSystems.Count();

            writerData.Write((ushort)c);
            foreach (var cs in data.Repository.CoordinateSystems.OrderBy(x => x.Code))
            {
                byte typeByte;
                switch (cs.TypeName.ToLower())
                {
                case "cartesian": typeByte = 16; break;

                case "ellipsoidal": typeByte = 32; break;

                case "spherical": typeByte = 48; break;

                case "vertical": typeByte = 64; break;

                default: throw new InvalidDataException();
                }
                var dimByte    = (byte)cs.Dimension;
                var typeDimVal = checked ((byte)(typeByte | dimByte));
                if (cs.Deprecated)
                {
                    typeDimVal |= 128;
                }

                writerData.Write((ushort)cs.Code);
                writerData.Write((byte)typeDimVal);
                writerData.Write((ushort)stringLookUp[cs.Name]);
            }
        }
Пример #16
0
        public static void WriteParamData(EpsgData data, BinaryWriter writerText, Func<ushort,BinaryWriter> paramFileGenerator)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.ParamTextValues.DistinctNonEmptyStrings()
            );

            foreach (var coordinateOpMethod in data.Repository.CoordinateOperationMethods) {
                var usedBy = coordinateOpMethod.UsedBy.OrderBy(x => x.Code).ToList();

                using(var writerData = paramFileGenerator((ushort)coordinateOpMethod.Code)) {
                    var paramUses = coordinateOpMethod.ParamUse.OrderBy(x => x.SortOrder).ToList();
                    writerData.Write((byte)paramUses.Count);
                    foreach (var paramUse in paramUses) {
                        writerData.Write((ushort)paramUse.Parameter.Code);
                        writerData.Write((byte)(paramUse.SignReversal.GetValueOrDefault() ? 0x01 : 0x02));
                    }
                    writerData.Write((ushort)usedBy.Count);
                    foreach (var coordinateOperation in usedBy) {
                        writerData.Write((ushort)coordinateOperation.Code);
                        var paramValues = coordinateOperation.ParameterValues.ToList();
                        foreach (var paramUse in paramUses) {
                            var paramCode = paramUse.Parameter.Code;
                            var paramValue = paramValues.SingleOrDefault(x => x.Parameter.Code == paramCode);

                            // the value
                            if(null != paramValue && paramValue.NumericValue.HasValue)
                                writerData.Write((ushort)data.GetNumberIndex(paramValue.NumericValue.Value));
                            else if(null != paramValue && !String.IsNullOrWhiteSpace(paramValue.TextValue))
                                writerData.Write((ushort)(stringLookUp[paramValue.TextValue] | 0x8000));
                            else
                                writerData.Write((ushort)0xffff);

                            // the uom of the value
                            if (null != paramValue && null != paramValue.Uom)
                                writerData.Write((ushort)paramValue.Uom.Code);
                            else
                                writerData.Write((ushort)0xffff);
                        }
                    }

                    writerData.Flush();
                }

            }
        }
Пример #17
0
        public static void WriteOpMethod(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.CoordinateOperationMethods.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            int c = data.Repository.CoordinateOperationMethods.Count();
            writerData.Write((ushort)c);
            foreach (var opMethod in data.Repository.CoordinateOperationMethods.OrderBy(x => x.Code)) {
                writerData.Write((ushort)opMethod.Code);
                writerData.Write((byte)(opMethod.Reverse ? 'B' : 'U'));
                writerData.Write((ushort)stringLookUp[opMethod.Name]);
            }
        }
Пример #18
0
 public static void WriteNumberLookUps(EpsgData data, BinaryWriter writerDouble, BinaryWriter writerInt, BinaryWriter writerShort)
 {
     foreach (var number in data.NumberLookUpDouble) {
         writerDouble.Write(number);
     }
     foreach (var number in data.NumberLookUpInt) {
         writerInt.Write((int)number);
     }
     foreach (var number in data.NumberLookUpShort) {
         writerShort.Write((short)number);
     }
 }
Пример #19
0
        public static void WriteMeridians(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                data.Repository.PrimeMeridians.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            int c = data.Repository.PrimeMeridians.Count();
            dataWriter.Write((ushort)c);
            foreach (var meridian in data.Repository.PrimeMeridians.OrderBy(x => x.Code)) {
                dataWriter.Write((ushort)meridian.Code);
                dataWriter.Write((ushort)meridian.Uom.Code);
                dataWriter.Write((ushort)data.GetNumberIndex(meridian.GreenwichLon));
                dataWriter.Write((byte)stringLookUp[meridian.Name]);
            }
        }
Пример #20
0
        public static void WriteEllipsoids(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                data.Repository.Ellipsoids.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            int c = data.Repository.Ellipsoids.Count();
            dataWriter.Write((ushort)c);
            foreach (var ellipsoid in data.Repository.Ellipsoids.OrderBy(x => x.Code)) {
                dataWriter.Write((ushort)ellipsoid.Code);
                dataWriter.Write((ushort)data.GetNumberIndex(ellipsoid.SemiMajorAxis));
                dataWriter.Write((ushort)data.GetNumberIndex(ellipsoid.InverseFlattening ?? ellipsoid.SemiMinorAxis ?? 0));
                dataWriter.Write((ushort)stringLookUp[ellipsoid.Name]);
                dataWriter.Write((byte)(ellipsoid.Uom.Code - 9000));
            }
        }
Пример #21
0
        public static void WriteDatums(EpsgData data, BinaryWriter engineeringWriter, BinaryWriter verticalWriter, BinaryWriter geodeticWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                data.Repository.Datums.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            foreach (var datumSet in data.Repository.Datums.GroupBy(x => x.Type)) {
                var datums = datumSet.OrderBy(x => x.Code);
                switch (datumSet.Key.ToUpper()) {
                    case "ENGINEERING":
                        engineeringWriter.Write((ushort)datums.Count());
                        foreach (var datum in datums) {
                            engineeringWriter.Write((ushort)datum.Code);
                            engineeringWriter.Write((ushort)(stringLookUp[datum.Name]));
                            engineeringWriter.Write((ushort)datum.AreaOfUse.Code);
                        }
                        break;
                    case "VERTICAL":
                        verticalWriter.Write((ushort)datums.Count());
                        foreach (var datum in datums) {
                            verticalWriter.Write((ushort)datum.Code);
                            verticalWriter.Write((ushort)(stringLookUp[datum.Name]));
                            verticalWriter.Write((ushort)datum.AreaOfUse.Code);
                        }
                        break;
                    case "GEODETIC":
                        geodeticWriter.Write((ushort)datums.Count());
                        foreach (var datum in datums) {
                            geodeticWriter.Write((ushort)datum.Code);
                            geodeticWriter.Write((ushort)(stringLookUp[datum.Name]));
                            geodeticWriter.Write((ushort)datum.AreaOfUse.Code);
                            geodeticWriter.Write((ushort)datum.Ellipsoid.Code);
                            geodeticWriter.Write((ushort)datum.PrimeMeridian.Code);
                        }
                        break;
                    default: throw new InvalidDataException("Invalid datum type: " + datumSet.Key);
                }
            }
        }
Пример #22
0
        public static void WriteCoordinateSystems(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.CoordinateSystems.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            int c = data.Repository.CoordinateSystems.Count();
            writerData.Write((ushort)c);
            foreach (var cs in data.Repository.CoordinateSystems.OrderBy(x => x.Code)) {

                byte typeByte;
                switch (cs.TypeName.ToLower()) {
                    case "cartesian": typeByte = 16; break;
                    case "ellipsoidal": typeByte = 32; break;
                    case "spherical": typeByte = 48; break;
                    case "vertical": typeByte = 64; break;
                    default: throw new InvalidDataException();
                }
                var dimByte = (byte)cs.Dimension;
                var typeDimVal = checked((byte)(typeByte | dimByte));
                if (cs.Deprecated)
                    typeDimVal |= 128;

                writerData.Write((ushort)cs.Code);
                writerData.Write((byte)typeDimVal);
                writerData.Write((ushort)stringLookUp[cs.Name]);
            }
        }
Пример #23
0
        public static void WriteCoordinateReferenceSystem(EpsgData data, BinaryWriter writerText, BinaryWriter writerNormal, BinaryWriter writerComposite)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.Crs.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            foreach (var crsGroup in data.Repository.Crs.Select(x => new { KindByte = ToCrsKindByte (x.Kind), Crs = x}).GroupBy(x => x.KindByte == 'C')) {
                var crsItemCount = crsGroup.Count();
                var crsItems = crsGroup.OrderBy(x => x.Crs.Code);
                var groupIsComposite = crsGroup.Key;
                if (groupIsComposite) {
                    writerComposite.Write((ushort)crsItemCount);
                    foreach (var crs in crsItems.Select(x => x.Crs)) {
                        writerComposite.Write((ushort)crs.Code);
                        writerComposite.Write((ushort)crs.CompoundHorizontalCrs.Code);
                        writerComposite.Write((ushort)crs.CompoundVerticalCrs.Code);
                        writerComposite.Write((ushort)crs.Area.Code);
                        writerComposite.Write((ushort)stringLookUp[crs.Name]);
                        writerComposite.Write((byte)(crs.Deprecated ? 0xff : 0));
                    }
                }
                else {
                    writerNormal.Write((ushort)crsItemCount);
                    foreach (var crsData in crsItems) {
                        var crs = crsData.Crs;
                        writerNormal.Write((uint)crs.Code);
                        var datum = GetFirstDatum(crs);
                        writerNormal.Write((ushort)(null == datum ? 0 : datum.Code));
                        writerNormal.Write((ushort)(crs.SourceGeographicCrs == null ? 0 : crs.SourceGeographicCrs.Code));
                        writerNormal.Write((ushort)(crs.Projection == null ? 0 : crs.Projection.Code));
                        writerNormal.Write((ushort)crs.CoordinateSystem.Code);
                        writerNormal.Write((ushort)crs.Area.Code);
                        writerNormal.Write((ushort)stringLookUp[crs.Name]);
                        writerNormal.Write((byte)(crs.Deprecated ? 0xff : 0));
                        writerNormal.Write((byte)crsData.KindByte);
                    }
                }

            }
        }
Пример #24
0
        public static void WriteAreas(EpsgData data, BinaryWriter dataWriter, BinaryWriter textWriter)
        {
            var areas = data.Repository.Areas.ToList();

            var stringLookUp = WriteTextDictionary(data, textWriter,
                                                   areas.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            var isos = new List <EpsgArea>();

            dataWriter.Write((ushort)areas.Count);
            foreach (var area in areas)
            {
                dataWriter.Write((ushort)area.Code);

                var encodedWestBound  = EncodeDegreeValueToShort(area.WestBound);
                var encodedEastBound  = EncodeDegreeValueToShort(area.EastBound);
                var encodedSouthBound = EncodeDegreeValueToShort(area.SouthBound);
                var encodedNorthBound = EncodeDegreeValueToShort(area.NorthBound);

// ReSharper disable CompareOfFloatsByEqualityOperator
                if (DecodeDegreeValueFromShort(encodedWestBound) != (area.WestBound ?? 0))
                {
                    throw new InvalidOperationException();
                }
                if (DecodeDegreeValueFromShort(encodedEastBound) != (area.EastBound ?? 0))
                {
                    throw new InvalidOperationException();
                }
                if (DecodeDegreeValueFromShort(encodedNorthBound) != (area.NorthBound ?? 0))
                {
                    throw new InvalidOperationException();
                }
                if (DecodeDegreeValueFromShort(encodedSouthBound) != (area.SouthBound ?? 0))
                {
                    throw new InvalidOperationException();
                }
// ReSharper restore CompareOfFloatsByEqualityOperator

                dataWriter.Write(encodedWestBound);
                dataWriter.Write(encodedEastBound);
                dataWriter.Write(encodedSouthBound);
                dataWriter.Write(encodedNorthBound);
                dataWriter.Write((ushort)stringLookUp[area.Name ?? String.Empty]);

                if (String.IsNullOrWhiteSpace(area.Iso2))
                {
                    dataWriter.Write((ushort)0);
                }
                else
                {
                    dataWriter.Write((byte)area.Iso2[0]);
                    dataWriter.Write((byte)area.Iso2[1]);
                }

                if (String.IsNullOrWhiteSpace(area.Iso3))
                {
                    dataWriter.Write((ushort)0);
                    dataWriter.Write((byte)0);
                }
                else
                {
                    dataWriter.Write((byte)area.Iso3[0]);
                    dataWriter.Write((byte)area.Iso3[1]);
                    dataWriter.Write((byte)area.Iso3[2]);
                }
            }
        }
Пример #25
0
        internal static void WriteOpPaths(EpsgData data, BinaryWriter writerOpForward, BinaryWriter writerOpReverse)
        {
            var crsBoundOps = data.Repository.CrsBoundCoordinateOperations;
            var forwardOpMappings = crsBoundOps.ToLookup(x => x.SourceCrs.Code, x => checked((ushort)x.Code));
            writerOpForward.Write((ushort)forwardOpMappings.Count);
            var pendingCodes = new List<ushort>();
            foreach (var map in forwardOpMappings.OrderBy(x => x.Key)) {
                var codes = map.OrderBy(x => x).ToList();
                writerOpForward.Write(checked((ushort)map.Key));
                writerOpForward.Write(checked((ushort)codes.Count));
                if (codes.Count == 1) {
                    writerOpForward.Write(codes[0]);
                }
                else {
                    writerOpForward.Write(checked((ushort)(pendingCodes.Count)));
                    pendingCodes.AddRange(codes);
                }
            }
            foreach (var c in pendingCodes) {
                writerOpForward.Write(c);
            }

            var reverseOpMappings = crsBoundOps.ToLookup(x => x.TargetCrs.Code, x => checked((ushort)x.Code));
            writerOpReverse.Write((ushort)reverseOpMappings.Count);
            pendingCodes = new List<ushort>();
            foreach (var map in reverseOpMappings.OrderBy(x => x.Key)) {
                var codes = map.OrderBy(x => x).ToList();
                writerOpReverse.Write(checked((ushort)map.Key));
                writerOpReverse.Write(checked((ushort)codes.Count));
                if (codes.Count == 1) {
                    writerOpReverse.Write(codes[0]);
                }
                else {
                    writerOpReverse.Write(checked((ushort)(pendingCodes.Count)));
                    pendingCodes.AddRange(codes);
                }
            }
            foreach (var c in pendingCodes) {
                writerOpReverse.Write(c);
            }
        }
Пример #26
0
        public static void WriteWordLookUp(EpsgData data, BinaryWriter textWriter, BinaryWriter indexWriter)
        {
            var roots = new List<TextNode>();
            foreach(var text in data.WordLookUpList) {
                var containerRoot = TextNode.FindContainingRoot(roots, text);
                if(null == containerRoot) {
                    containerRoot = new TextNode(text);
                    var containedRoots = roots.Where(r => containerRoot.Contains(r.Text)).ToList();
                    foreach(var containedRoot in containedRoots) {
                        roots.Remove(containedRoot);
                        if(!containerRoot.Add(containedRoot)) {
                            throw new InvalidOperationException();
                        }
                    }
                    roots.Add(containerRoot);
                }else {
                    if(!containerRoot.Add(text)) {
                        throw new InvalidOperationException();
                    }
                }
            }

            for (int quality = Math.Min(6,roots.Select(x => x.Text.Length).Max()/2); quality >= 0; quality--) {
                for (int i = 0; i < roots.Count; i++) {
                    for (int j = i + 1; j < roots.Count; j++) {
                        int overlapAt = StringUtils.OverlapIndex(roots[i].Text, roots[j].Text);
                        if (overlapAt >= 0 && (roots[i].Text.Length - overlapAt) >= quality) {
                            var newText = roots[i].Text.Substring(0, overlapAt) + roots[j].Text;
                            var newNode = new TextNode(newText, new[]{roots[i], roots[j]});
                            roots.RemoveAt(j);
                            roots[i] = newNode;
                            i--;
                            break;
                        }
                        overlapAt = StringUtils.OverlapIndex(roots[j].Text, roots[i].Text);
                        if (overlapAt >= 0 && (roots[j].Text.Length - overlapAt) >= quality) {
                            var newText = roots[j].Text.Substring(0, overlapAt) + roots[i].Text;
                            var newNode = new TextNode(newText, new[]{roots[j], roots[i]});
                            roots.RemoveAt(j);
                            roots[i] = newNode;
                            i--;
                            break;
                        }
                    }
                }
            }

            var offsetLookUp = new Dictionary<string, int>();
            int rootOffset = 0;
            foreach(var root in roots) {
                var rootText = root.Text;
                var rootBytes = Encoding.UTF8.GetBytes(rootText);
                textWriter.Write(rootBytes);
                foreach(var text in root.GetAllString()) {
                    int startIndex = rootText.IndexOf(text, StringComparison.Ordinal);
                    var localOffset = Encoding.UTF8.GetByteCount(rootText.Substring(0, startIndex));
                    offsetLookUp.Add(text, rootOffset + localOffset);
                }
                rootOffset += rootBytes.Length;
            }

            foreach(var word in data.WordLookUpList) {
                indexWriter.Write((ushort)offsetLookUp[word]);
                indexWriter.Write((byte)(Encoding.UTF8.GetByteCount(word)));
            }
        }
Пример #27
0
        public static void WriteParameters(EpsgData data, BinaryWriter writerData, BinaryWriter writerText)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.Parameters.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            int c = data.Repository.Parameters.Count();
            writerData.Write((ushort)c);
            foreach (var parameter in data.Repository.Parameters.OrderBy(x => x.Code)) {
                writerData.Write((ushort)parameter.Code);
                writerData.Write((ushort)stringLookUp[parameter.Name]);
            }
        }
Пример #28
0
        public static void WriteUnitOfMeasures(EpsgData data, BinaryWriter lengthWriter, BinaryWriter angleWriter, BinaryWriter scaleWriter, BinaryWriter timeWriter, BinaryWriter textWriter)
        {
            var stringLookUp = WriteTextDictionary(data, textWriter,
                data.Repository.Uoms.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            var uomGroups = data.Repository.Uoms.GroupBy(x => x.Type.ToUpper());
            foreach (var uomGroup in uomGroups) {
                BinaryWriter writer;
                if (uomGroup.Key == "LENGTH")
                    writer = lengthWriter;
                else if (uomGroup.Key == "ANGLE")
                    writer = angleWriter;
                else if (uomGroup.Key == "SCALE")
                    writer = scaleWriter;
                else if (uomGroup.Key == "TIME")
                    writer = timeWriter;
                else
                    throw new InvalidDataException("Invalid uom type: " + uomGroup.Key);

                writer.Write((ushort)uomGroup.Count());
                foreach (var uom in uomGroup.OrderBy(x => x.Code)) {
                    writer.Write((ushort)uom.Code);
                    writer.Write((ushort)stringLookUp[uom.Name]);
                    writer.Write((ushort)data.GetNumberIndex(uom.FactorB ?? 0));
                    writer.Write((ushort)data.GetNumberIndex(uom.FactorC ?? 0));
                }
            }
        }
Пример #29
0
        public static void WriteCoordinateOperations(EpsgData data, BinaryWriter writerText, BinaryWriter writerDataConversion, BinaryWriter writerDataTransformation, BinaryWriter writerDataConcatenated, BinaryWriter writerDataPath)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                                                   data.Repository.CoordinateOperations.Select(x => x.Name).DistinctNonEmptyStrings()
                                                   );

            var opGroups = data.Repository.CoordinateOperations.GroupBy(x => x.TypeName.ToLower());

            foreach (var opGroup in opGroups)
            {
                var ops      = opGroup.OrderBy(x => x.Code);
                var typeName = opGroup.Key;
                switch (typeName)
                {
                case "transformation": {
                    writerDataTransformation.Write((ushort)ops.Count());
                    foreach (var op in ops)
                    {
                        writerDataTransformation.Write((ushort)op.Code);
                        writerDataTransformation.Write((ushort)op.SourceCrs.Code);
                        writerDataTransformation.Write((ushort)op.TargetCrs.Code);
                        writerDataTransformation.Write((ushort)op.Method.Code);
                        writerDataTransformation.Write((ushort)data.GetNumberIndex(op.Accuracy ?? 999));
                        writerDataTransformation.Write((ushort)op.Area.Code);
                        writerDataTransformation.Write((byte)(op.Deprecated ? 0xff : 0));
                        writerDataTransformation.Write((ushort)stringLookUp[op.Name]);
                    }
                    break;
                }

                case "conversion": {
                    writerDataConversion.Write((ushort)ops.Count());
                    foreach (var op in ops)
                    {
                        writerDataConversion.Write((ushort)op.Code);
                        writerDataConversion.Write((ushort)op.Method.Code);
                        writerDataConversion.Write((ushort)op.Area.Code);
                        writerDataConversion.Write((byte)(op.Deprecated ? 0xff : 0));
                        writerDataConversion.Write((ushort)stringLookUp[op.Name]);
                    }
                    break;
                }

                case "concatenated operation": {
                    var pathOffset = 0;
                    writerDataConcatenated.Write((ushort)ops.Count());

                    foreach (var op in ops)
                    {
                        var catOps = data.Repository.CoordOpPathItems
                                     .Where(x => x.CatCode == op.Code)
                                     .OrderBy(x => x.Step)
                                     .ToList();
                        foreach (var catOp in catOps)
                        {
                            writerDataPath.Write((ushort)catOp.Operation.Code);
                        }

                        writerDataConcatenated.Write((ushort)op.Code);
                        writerDataConcatenated.Write((ushort)op.SourceCrs.Code);
                        writerDataConcatenated.Write((ushort)op.TargetCrs.Code);
                        writerDataConcatenated.Write((ushort)op.Area.Code);
                        writerDataConcatenated.Write((byte)(op.Deprecated ? 0xff : 0));
                        writerDataConcatenated.Write((ushort)stringLookUp[op.Name]);
                        writerDataConcatenated.Write((byte)(catOps.Count));
                        writerDataConcatenated.Write((ushort)pathOffset);

                        pathOffset += catOps.Count * sizeof(ushort);
                    }
                    break;
                }

                default: throw new NotSupportedException();
                }
            }
        }
Пример #30
0
        internal static void WriteFromBase(EpsgData epsgData, BinaryWriter writerFromBaseShort, BinaryWriter writerFromBaseWide)
        {
            var sizedGroups = epsgData.Repository.Crs
                .GroupBy(x => x.Code >= 0 && x.Code <= UInt16.MaxValue, x => x)
                .ToList();

            var shortGroup = sizedGroups.Single(x => x.Key)
                .Where(x => x.SourceGeographicCrs != null)
                .GroupBy(x => x.SourceGeographicCrs.Code, x => x.Code)
                .ToList();
            writerFromBaseShort.Write(checked((ushort)shortGroup.Count));
            var shortBulkCodes = new List<ushort>();
            foreach (var set in shortGroup.OrderBy(x => x.Key)) {
                var codes = set.Select(x => checked((ushort)x)).OrderBy(x => x).ToArray();
                writerFromBaseShort.Write(checked((ushort)set.Key));
                writerFromBaseShort.Write(checked((ushort)codes.Length));
                if (codes.Length == 1) {
                    writerFromBaseShort.Write(codes[0]);
                }
                else {
                    writerFromBaseShort.Write(checked((ushort)shortBulkCodes.Count));
                    shortBulkCodes.AddRange(codes);
                }
            }
            foreach (var code in shortBulkCodes) {
                writerFromBaseShort.Write(code);
            }

            var wideGroup = sizedGroups.Single(x => !x.Key)
                .Where(x => x.SourceGeographicCrs != null)
                .GroupBy(x => x.SourceGeographicCrs.Code, x => x.Code)
                .ToList();
            writerFromBaseWide.Write(checked((ushort)wideGroup.Count));
            var wideBulkCodes = new List<int>();
            foreach (var set in wideGroup.OrderBy(x => x.Key)) {
                var codes = set.OrderBy(x => x).ToArray();
                writerFromBaseWide.Write(checked((ushort)set.Key));
                writerFromBaseWide.Write(checked((ushort)codes.Length));
                if (codes.Length == 1) {
                    writerFromBaseWide.Write(codes[0]);
                }
                else {
                    writerFromBaseWide.Write(wideBulkCodes.Count);
                    wideBulkCodes.AddRange(codes);
                }
            }
            foreach (var code in wideBulkCodes) {
                writerFromBaseWide.Write(code);
            }
        }
Пример #31
0
        internal static void WriteFromBase(EpsgData epsgData, BinaryWriter writerFromBaseShort, BinaryWriter writerFromBaseWide)
        {
            var sizedGroups = epsgData.Repository.Crs
                              .GroupBy(x => x.Code >= 0 && x.Code <= UInt16.MaxValue, x => x)
                              .ToList();

            var shortGroup = sizedGroups.Single(x => x.Key)
                             .Where(x => x.SourceGeographicCrs != null)
                             .GroupBy(x => x.SourceGeographicCrs.Code, x => x.Code)
                             .ToList();

            writerFromBaseShort.Write(checked ((ushort)shortGroup.Count));
            var shortBulkCodes = new List <ushort>();

            foreach (var set in shortGroup.OrderBy(x => x.Key))
            {
                var codes = set.Select(x => checked ((ushort)x)).OrderBy(x => x).ToArray();
                writerFromBaseShort.Write(checked ((ushort)set.Key));
                writerFromBaseShort.Write(checked ((ushort)codes.Length));
                if (codes.Length == 1)
                {
                    writerFromBaseShort.Write(codes[0]);
                }
                else
                {
                    writerFromBaseShort.Write(checked ((ushort)shortBulkCodes.Count));
                    shortBulkCodes.AddRange(codes);
                }
            }
            foreach (var code in shortBulkCodes)
            {
                writerFromBaseShort.Write(code);
            }

            var wideGroup = sizedGroups.Single(x => !x.Key)
                            .Where(x => x.SourceGeographicCrs != null)
                            .GroupBy(x => x.SourceGeographicCrs.Code, x => x.Code)
                            .ToList();

            writerFromBaseWide.Write(checked ((ushort)wideGroup.Count));
            var wideBulkCodes = new List <int>();

            foreach (var set in wideGroup.OrderBy(x => x.Key))
            {
                var codes = set.OrderBy(x => x).ToArray();
                writerFromBaseWide.Write(checked ((ushort)set.Key));
                writerFromBaseWide.Write(checked ((ushort)codes.Length));
                if (codes.Length == 1)
                {
                    writerFromBaseWide.Write(codes[0]);
                }
                else
                {
                    writerFromBaseWide.Write(wideBulkCodes.Count);
                    wideBulkCodes.AddRange(codes);
                }
            }
            foreach (var code in wideBulkCodes)
            {
                writerFromBaseWide.Write(code);
            }
        }
Пример #32
0
 private static Dictionary<string, ushort> WriteTextDictionary(EpsgData data, BinaryWriter textWriter, IEnumerable<string> allStrings)
 {
     var stringLookUp = new Dictionary<string, ushort>();
     int textOffset = 0;
     foreach (var textItem in allStrings) {
         var textBytes = data.GenerateWordIndexBytes(textItem);
         textWriter.Write((byte)textBytes.Length);
         textWriter.Write(textBytes);
         stringLookUp.Add(textItem, (ushort)textOffset);
         textOffset += textBytes.Length + sizeof(byte);
     }
     stringLookUp.Add(String.Empty, ushort.MaxValue);
     return stringLookUp;
 }
Пример #33
0
        public static void WriteCoordinateOperations(EpsgData data, BinaryWriter writerText, BinaryWriter writerDataConversion, BinaryWriter writerDataTransformation, BinaryWriter writerDataConcatenated, BinaryWriter writerDataPath)
        {
            var stringLookUp = WriteTextDictionary(data, writerText,
                data.Repository.CoordinateOperations.Select(x => x.Name).DistinctNonEmptyStrings()
            );

            var opGroups = data.Repository.CoordinateOperations.GroupBy(x => x.TypeName.ToLower());

            foreach (var opGroup in opGroups) {
                var ops = opGroup.OrderBy(x => x.Code);
                var typeName = opGroup.Key;
                switch (typeName) {
                    case "transformation": {
                        writerDataTransformation.Write((ushort)ops.Count());
                        foreach (var op in ops) {
                            writerDataTransformation.Write((ushort)op.Code);
                            writerDataTransformation.Write((ushort)op.SourceCrs.Code);
                            writerDataTransformation.Write((ushort)op.TargetCrs.Code);
                            writerDataTransformation.Write((ushort)op.Method.Code);
                            writerDataTransformation.Write((ushort)data.GetNumberIndex(op.Accuracy ?? 999));
                            writerDataTransformation.Write((ushort)op.Area.Code);
                            writerDataTransformation.Write((byte)(op.Deprecated ? 0xff : 0));
                            writerDataTransformation.Write((ushort)stringLookUp[op.Name]);
                        }
                        break;
                    }
                    case "conversion": {
                        writerDataConversion.Write((ushort)ops.Count());
                        foreach (var op in ops) {
                            writerDataConversion.Write((ushort)op.Code);
                            writerDataConversion.Write((ushort)op.Method.Code);
                            writerDataConversion.Write((ushort)op.Area.Code);
                            writerDataConversion.Write((byte)(op.Deprecated ? 0xff : 0));
                            writerDataConversion.Write((ushort)stringLookUp[op.Name]);
                        }
                        break;
                    }
                    case "concatenated operation": {
                        var pathOffset = 0;
                        writerDataConcatenated.Write((ushort)ops.Count());

                        foreach (var op in ops) {
                            var catOps = data.Repository.CoordOpPathItems
                                .Where(x => x.CatCode == op.Code)
                                .OrderBy(x => x.Step)
                                .ToList();
                            foreach (var catOp in catOps) {
                                writerDataPath.Write((ushort)catOp.Operation.Code);
                            }

                            writerDataConcatenated.Write((ushort)op.Code);
                            writerDataConcatenated.Write((ushort)op.SourceCrs.Code);
                            writerDataConcatenated.Write((ushort)op.TargetCrs.Code);
                            writerDataConcatenated.Write((ushort)op.Area.Code);
                            writerDataConcatenated.Write((byte)(op.Deprecated ? 0xff : 0));
                            writerDataConcatenated.Write((ushort)stringLookUp[op.Name]);
                            writerDataConcatenated.Write((byte)(catOps.Count));
                            writerDataConcatenated.Write((ushort)pathOffset);

                            pathOffset += catOps.Count * sizeof(ushort);
                        }
                        break;
                    }
                    default: throw new NotSupportedException();
                }
            }
        }
Пример #34
0
        static void Main(string[] args)
        {
            string dataFolderPath = "data";

            if (args.Length > 0 && !String.IsNullOrWhiteSpace(args[0]))
            {
                dataFolderPath = Path.GetFullPath(args[0]);
            }

            var alternatePath = @"../../../data";

            if (Directory.Exists(dataFolderPath))
            {
                ;
            }
            else if (Directory.Exists(alternatePath))
            {
                dataFolderPath = alternatePath;
            }
            else
            {
                throw new IOException("Folder does not exist: " + dataFolderPath);
            }

            var dataFilePath = GetDatabasePath(dataFolderPath);

            if (null == dataFilePath || !File.Exists(dataFilePath))
            {
                throw new FileNotFoundException("Database file not found.");
            }
            Console.WriteLine("Found database: " + dataFilePath);

            var outFolder = Path.Combine(dataFolderPath, "out");

            if (!Directory.Exists(outFolder))
            {
                Directory.CreateDirectory(outFolder);
            }

            using (var repository = new EpsgRepository(new FileInfo(dataFilePath))) {
                var epsgData = new EpsgData(repository);

                epsgData.WordLookUpList = StringUtils.BuildWordCountLookUp(
                    Concat(
                        epsgData.Repository.AreaNames,
                        ExtractStrings(epsgData.Repository.Axes, o => o.Name, o => o.Orientation, o => o.Abbreviation),
                        epsgData.Repository.CrsNames,
                        epsgData.Repository.CoordinateSystemNames,
                        epsgData.Repository.CoordinateOperationNames,
                        epsgData.Repository.CoordinateOperationMethodNames,
                        ExtractStrings(epsgData.Repository.Parameters, o => o.Name, o => o.Description),
                        epsgData.Repository.ParamTextValues,
                        epsgData.Repository.DatumNames,
                        epsgData.Repository.EllipsoidNames,
                        epsgData.Repository.PrimeMeridianNames,
                        epsgData.Repository.UomNames
                        )
                    .Where(x => x != null)
                    .SelectMany(StringUtils.BreakIntoWordParts)
                    )
                                          .OrderByDescending(o => o.Value)
                                          .ThenBy(o => o.Key.Length)
                                          .Select(o => o.Key)
                                          .ToList();

                using (var streamIndex = File.Open(Path.Combine(outFolder, "words.dat"), FileMode.Create))
                    using (var writerIndex = new BinaryWriter(streamIndex))
                        using (var streamText = File.Open(Path.Combine(outFolder, "words.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteWordLookUp(epsgData, writerText, writerIndex);

                epsgData.SetNumberLists(NumberUtils.BuildNumberCountLookUp(Concat(
                                                                               //ExtractDoubles(epsgData.Areas, o => o.EastBound, o => o.WestBound, o => o.SouthBound, o => o.NorthBound),
                                                                               ExtractDoubles(epsgData.Repository.CoordinateOperations, o => o.Accuracy),
                                                                               ExtractDoubles(epsgData.Repository.Ellipsoids, o => o.SemiMajorAxis, o => o.SemiMinorAxis, o => o.InverseFlattening),
                                                                               ExtractDoubles(epsgData.Repository.ParamValues, o => o.NumericValue),
                                                                               ExtractDoubles(epsgData.Repository.PrimeMeridians, o => o.GreenwichLon),
                                                                               ExtractDoubles(epsgData.Repository.Uoms, o => o.FactorB, o => o.FactorC)
                                                                               ))
                                        .OrderByDescending(o => o.Value)
                                        .Select(o => o.Key)
                                        );

                using (var streamDouble = File.Open(Path.Combine(outFolder, "numbersd.dat"), FileMode.Create))
                    using (var writerDouble = new BinaryWriter(streamDouble))
                        using (var streamInt = File.Open(Path.Combine(outFolder, "numbersi.dat"), FileMode.Create))
                            using (var writerInt = new BinaryWriter(streamInt))
                                using (var streamShort = File.Open(Path.Combine(outFolder, "numberss.dat"), FileMode.Create))
                                    using (var writerShort = new BinaryWriter(streamShort))
                                        WriterUtils.WriteNumberLookUps(epsgData, writerDouble, writerInt, writerShort);

                using (var streamOpForward = File.Open(Path.Combine(outFolder, "txfrom.dat"), FileMode.Create))
                    using (var writerOpForward = new BinaryWriter(streamOpForward))
                        using (var streamOpReverse = File.Open(Path.Combine(outFolder, "txto.dat"), FileMode.Create))
                            using (var writerOpReverse = new BinaryWriter(streamOpReverse))
                                WriterUtils.WriteOpPaths(epsgData, writerOpForward, writerOpReverse);

                using (var streamFromBase2 = File.Open(Path.Combine(outFolder, "crsfrombase.dat"), FileMode.Create))
                    using (var writerFromBase2 = new BinaryWriter(streamFromBase2))
                        using (var streamFromBase4 = File.Open(Path.Combine(outFolder, "crsfrombase_wide.dat"), FileMode.Create))
                            using (var writerFromBase4 = new BinaryWriter(streamFromBase4))
                                WriterUtils.WriteFromBase(epsgData, writerFromBase2, writerFromBase4);

                using (var streamData = File.Open(Path.Combine(outFolder, "areas.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "areas.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteAreas(epsgData, writerData, writerText);

                using (var streamText = File.Open(Path.Combine(outFolder, "axis.txt"), FileMode.Create))
                    using (var writerText = new BinaryWriter(streamText))
                        using (var stream1Data = File.Open(Path.Combine(outFolder, "axis1.dat"), FileMode.Create))
                            using (var writer1Data = new BinaryWriter(stream1Data))
                                using (var stream2Data = File.Open(Path.Combine(outFolder, "axis2.dat"), FileMode.Create))
                                    using (var writer2Data = new BinaryWriter(stream2Data))
                                        using (var stream3Data = File.Open(Path.Combine(outFolder, "axis3.dat"), FileMode.Create))
                                            using (var writer3Data = new BinaryWriter(stream3Data))
                                                WriterUtils.WriteAxes(epsgData, writerText, writer1Data, writer2Data, writer3Data);

                using (var streamData = File.Open(Path.Combine(outFolder, "ellipsoids.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "ellipsoids.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteEllipsoids(epsgData, writerData, writerText);

                using (var streamData = File.Open(Path.Combine(outFolder, "meridians.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "meridians.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteMeridians(epsgData, writerData, writerText);

                using (var streamDataEngineering = File.Open(Path.Combine(outFolder, "datumegr.dat"), FileMode.Create))
                    using (var writerDataEngineering = new BinaryWriter(streamDataEngineering))
                        using (var streamDataVertical = File.Open(Path.Combine(outFolder, "datumver.dat"), FileMode.Create))
                            using (var writerDataVertical = new BinaryWriter(streamDataVertical))
                                using (var streamDataGeo = File.Open(Path.Combine(outFolder, "datumgeo.dat"), FileMode.Create))
                                    using (var writerDataGeo = new BinaryWriter(streamDataGeo))
                                        using (var streamText = File.Open(Path.Combine(outFolder, "datums.txt"), FileMode.Create))
                                            using (var writerText = new BinaryWriter(streamText))
                                                WriterUtils.WriteDatums(epsgData, writerDataEngineering, writerDataVertical, writerDataGeo, writerText);

                using (var streamDataLength = File.Open(Path.Combine(outFolder, "uomlength.dat"), FileMode.Create))
                    using (var writerDataLength = new BinaryWriter(streamDataLength))
                        using (var streamDataAngle = File.Open(Path.Combine(outFolder, "uomangle.dat"), FileMode.Create))
                            using (var writerDataAngle = new BinaryWriter(streamDataAngle))
                                using (var streamDataScale = File.Open(Path.Combine(outFolder, "uomscale.dat"), FileMode.Create))
                                    using (var writerDataScale = new BinaryWriter(streamDataScale))
                                        using (var streamDataTime = File.Open(Path.Combine(outFolder, "uomtime.dat"), FileMode.Create))
                                            using (var writerDataTime = new BinaryWriter(streamDataTime))
                                                using (var streamText = File.Open(Path.Combine(outFolder, "uoms.txt"), FileMode.Create))
                                                    using (var writerText = new BinaryWriter(streamText))
                                                        WriterUtils.WriteUnitOfMeasures(epsgData, writerDataLength, writerDataAngle, writerDataScale, writerDataTime, writerText);

                using (var streamData = File.Open(Path.Combine(outFolder, "parameters.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "parameters.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteParameters(epsgData, writerData, writerText);

                using (var streamData = File.Open(Path.Combine(outFolder, "opmethod.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "opmethod.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteOpMethod(epsgData, writerData, writerText);

                using (var streamData = File.Open(Path.Combine(outFolder, "coordsys.dat"), FileMode.Create))
                    using (var writerData = new BinaryWriter(streamData))
                        using (var streamText = File.Open(Path.Combine(outFolder, "coordsys.txt"), FileMode.Create))
                            using (var writerText = new BinaryWriter(streamText))
                                WriterUtils.WriteCoordinateSystems(epsgData, writerData, writerText);

                using (var streamText = File.Open(Path.Combine(outFolder, "params.txt"), FileMode.Create))
                    using (var writerText = new BinaryWriter(streamText))
                        WriterUtils.WriteParamData(
                            epsgData, writerText,
                            code => new BinaryWriter(
                                File.Open(
                                    Path.Combine(outFolder, String.Format("param{0}.dat", code)),
                                    FileMode.Create
                                    )
                                )
                            );

                using (var streamDataNormal = File.Open(Path.Combine(outFolder, "crs.dat"), FileMode.Create))
                    using (var writerDataNormal = new BinaryWriter(streamDataNormal))
                        using (var streamDataComposite = File.Open(Path.Combine(outFolder, "crscmp.dat"), FileMode.Create))
                            using (var writerDataComposite = new BinaryWriter(streamDataComposite))
                                using (var streamText = File.Open(Path.Combine(outFolder, "crs.txt"), FileMode.Create))
                                    using (var writerText = new BinaryWriter(streamText))
                                        WriterUtils.WriteCoordinateReferenceSystem(epsgData, writerText, writerDataNormal, writerDataComposite);

                using (var streamDataConversion = File.Open(Path.Combine(outFolder, "opconv.dat"), FileMode.Create))
                    using (var writerDataConversion = new BinaryWriter(streamDataConversion))
                        using (var streamDataConcat = File.Open(Path.Combine(outFolder, "opcat.dat"), FileMode.Create))
                            using (var writerDataConcat = new BinaryWriter(streamDataConcat))
                                using (var streamDataTransform = File.Open(Path.Combine(outFolder, "optran.dat"), FileMode.Create))
                                    using (var writerDataTransform = new BinaryWriter(streamDataTransform))
                                        using (var streamDataPath = File.Open(Path.Combine(outFolder, "oppath.dat"), FileMode.Create))
                                            using (var writerDataPath = new BinaryWriter(streamDataPath))
                                                using (var streamText = File.Open(Path.Combine(outFolder, "op.txt"), FileMode.Create))
                                                    using (var writerText = new BinaryWriter(streamText))
                                                        WriterUtils.WriteCoordinateOperations(epsgData, writerText, writerDataConversion, writerDataTransform, writerDataConcat, writerDataPath);
            }
        }
Пример #35
0
        public static void WriteWordLookUp(EpsgData data, BinaryWriter textWriter, BinaryWriter indexWriter)
        {
            var roots = new List <TextNode>();

            foreach (var text in data.WordLookUpList)
            {
                var containerRoot = TextNode.FindContainingRoot(roots, text);
                if (null == containerRoot)
                {
                    containerRoot = new TextNode(text);
                    var containedRoots = roots.Where(r => containerRoot.Contains(r.Text)).ToList();
                    foreach (var containedRoot in containedRoots)
                    {
                        roots.Remove(containedRoot);
                        if (!containerRoot.Add(containedRoot))
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    roots.Add(containerRoot);
                }
                else
                {
                    if (!containerRoot.Add(text))
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            for (int quality = Math.Min(6, roots.Select(x => x.Text.Length).Max() / 2); quality >= 0; quality--)
            {
                for (int i = 0; i < roots.Count; i++)
                {
                    for (int j = i + 1; j < roots.Count; j++)
                    {
                        int overlapAt = StringUtils.OverlapIndex(roots[i].Text, roots[j].Text);
                        if (overlapAt >= 0 && (roots[i].Text.Length - overlapAt) >= quality)
                        {
                            var newText = roots[i].Text.Substring(0, overlapAt) + roots[j].Text;
                            var newNode = new TextNode(newText, new[] { roots[i], roots[j] });
                            roots.RemoveAt(j);
                            roots[i] = newNode;
                            i--;
                            break;
                        }
                        overlapAt = StringUtils.OverlapIndex(roots[j].Text, roots[i].Text);
                        if (overlapAt >= 0 && (roots[j].Text.Length - overlapAt) >= quality)
                        {
                            var newText = roots[j].Text.Substring(0, overlapAt) + roots[i].Text;
                            var newNode = new TextNode(newText, new[] { roots[j], roots[i] });
                            roots.RemoveAt(j);
                            roots[i] = newNode;
                            i--;
                            break;
                        }
                    }
                }
            }

            var offsetLookUp = new Dictionary <string, int>();
            int rootOffset   = 0;

            foreach (var root in roots)
            {
                var rootText  = root.Text;
                var rootBytes = Encoding.UTF8.GetBytes(rootText);
                textWriter.Write(rootBytes);
                foreach (var text in root.GetAllString())
                {
                    int startIndex  = rootText.IndexOf(text, StringComparison.Ordinal);
                    var localOffset = Encoding.UTF8.GetByteCount(rootText.Substring(0, startIndex));
                    offsetLookUp.Add(text, rootOffset + localOffset);
                }
                rootOffset += rootBytes.Length;
            }

            foreach (var word in data.WordLookUpList)
            {
                indexWriter.Write((ushort)offsetLookUp[word]);
                indexWriter.Write((byte)(Encoding.UTF8.GetByteCount(word)));
            }
        }