Exemplo n.º 1
0
		/// <summary>
		/// Gets the coordinates from specified district key.
		/// </summary>
		/// <returns>The coordinates. Multiple group of coordinates separated by top level array element.</returns>
		/// <param name="districtKey">District key as country-district-...</param>
		public static IEnumerable<IEnumerable<Coordinate>> GetCoordinates(String districtKey)
		{
			var geo = new List<IEnumerable<Coordinate>>();

			if (districtKey == null)
				return null;

			var level = 0;
			var distictKeys = districtKey.Split('-');

			if (districtKey != null)
				level = districtKey.Split('-').Length - 1;

			var rootKey = distictKeys[0];

			if (!shapeFileInfoLookup.ContainsKey(rootKey))
				throw new KeyNotFoundException("Key = " + rootKey + " not found from configuration.");

			var levelMap = shapeFileInfoLookup[rootKey].ShapeFileMaps.FirstOrDefault(m => m.Level == level);
			if (levelMap == null)
			{
				throw new KeyNotFoundException(
					"No ShapeFile entry for Level = " + level + " computed from: " + districtKey);
			}

			var rootPath = shapeFileInfoLookup[rootKey].ShapeFilesRootPath;
			var fileName = shapeFileInfoLookup[rootKey].ShapeFileMaps[level].FileName;
			var filePath = rootPath + fileName;
			var cachePath = coordCachePath;

			if (HttpContext.Current != null)
			{
				filePath = HttpContext.Current.Server.MapPath(filePath);

				if(cachePath != null)
					cachePath = HttpContext.Current.Server.MapPath(cachePath + "/" + districtKey);
			}

			// Get coordinate from cache instead if found.
			if (cachePath != null && File.Exists(cachePath))
			{
				try
				{
					using (var streamReader = File.OpenText(cachePath))
					{
						String s = streamReader.ReadToEnd();
						var coordinates = s.Split('|').Select(
							ss => { 
								var areas = ss.Split('-').Select(
									ax => {

										var p = ax.Split(',');
										return new Coordinate { 
											X = Double.Parse(p[0]),
											Y = Double.Parse(p[1])
										};
									});

								return areas;
							});

						if (coordinates.Any(Enumerable.Any))
							geo.AddRange(coordinates);
					}

					return geo;
				}
				catch(Exception ex)
				{
					//TODO: Log this exception.
					Console.WriteLine(ex.Message);
				}
			}

			var factory = new GeometryFactory();
			using (var shapeFileDataReader = new ShapefileDataReader(filePath, factory))
			{
				var shapeHeader = shapeFileDataReader.ShapeHeader;
				var bounds = shapeHeader.Bounds;
				var header = shapeFileDataReader.DbaseHeader;

				shapeFileDataReader.Reset();

				while (shapeFileDataReader.Read())
				{
					var keys = new string[header.NumFields];
					var geometry = shapeFileDataReader.Geometry;
					var shapeDisticts = new List<String>();

					for (var i = 0; i < header.NumFields; i++)
					{
						var fieldDescriptor = header.Fields[i];
						keys[i] = fieldDescriptor.Name;

						var fieldValue = shapeFileDataReader.GetValue(i) + "";

						for (var j = 0; j <= level; j++)
						{
							if (fieldDescriptor.Name == "NAME_" + j)
							{
								shapeDisticts.Add(fieldValue.ToLower());
							}
						}
					}

					var shapeDistictKey = String.Join("-", shapeDisticts.ToArray());
					Console.WriteLine(shapeDistictKey);

					if (districtKey == shapeDistictKey)
					{
						// Find the duplicate coordinates. It is the polygon loop.
						var endPointLookup = geometry.Coordinates.
						                     GroupBy(k => k.X + "," + k.Y).
						                     Where(g => g.Count() >= 2).
						                     ToLookup(g => g.Key, null);

						String endPoint = null;
						var coords = new List<Coordinate>();

						try
						{
							for (long i = 0; i < geometry.Coordinates.LongLength; i++)
							{
								if(geometry.Coordinates[i] == null)
									continue;

								var key = geometry.Coordinates[i].X + "," +
								          geometry.Coordinates[i].Y;

								coords.Add(geometry.Coordinates[i]);

								if (endPoint == null)
								{
									if (endPointLookup.Contains(key))
										endPoint = key;
								}
								else
								{
									if (endPoint == key)
									{
										endPoint = null;
										geo.Add(coords);
										coords = new List<Coordinate>();
									}
								}
							}
						}
						catch(Exception ex)
						{
							Console.WriteLine(ex.Message);
							throw;
						}

						break;
					}
				}

				shapeFileDataReader.Close();
				shapeFileDataReader.Dispose();
			}

			// Build cache.
			if (cachePath != null)
			{
				var physicalCachePath = coordCachePath;

				if (HttpContext.Current != null)
					physicalCachePath = HttpContext.Current.Server.MapPath(physicalCachePath);

				if (!Directory.Exists(physicalCachePath))
					Directory.CreateDirectory(physicalCachePath);

				var sb = new StringBuilder();
				foreach (var coords in geo)
				{
					foreach (var coord in coords)
					{
						sb.AppendFormat("{0},{1}", coord.X, coord.Y);
						sb.Append("-");
					}

					if(sb.Length > 0)
						sb.Remove(sb.Length - 1, 1);

					sb.Append("|");
				}

				if(sb.Length > 0)
					sb.Remove(sb.Length - 1, 1);

				var coordCache = sb.ToString();
				File.WriteAllText(cachePath, coordCache);
			}

			return geo;
		}
Exemplo n.º 2
0
        public bool ImportShapes(List<string> files, bool latlon, bool useShapeProps, bool useElev, bool elevFeet)
        {
            GeometryFactory factory;
            ShapefileDataReader shapeFileDataReader;
            ArrayList features;
            Feature feature;
            AttributesTable attributesTable;
            string[] keys;
            Geometry geometry;
            DbaseFieldDescriptor fldDescriptor;
            int polyCount = (int)dal.GetPolyCount();

            GpsPoint gps;
            int index = 0;

            _Polygons = new Dictionary<string, TtPolygon>();
            _Points = new List<TtPoint>();

            List<TtPoint> tmpPoints = new List<TtPoint>();

            try
            {
                foreach (string file in files)
                {
                    //polyCount = 1;

                    factory = new GeometryFactory();
                    shapeFileDataReader = new ShapefileDataReader(file, factory);
                    DbaseFileHeader header = shapeFileDataReader.DbaseHeader;

                    features = new ArrayList();
                    while (shapeFileDataReader.Read())
                    {
                        feature = new Feature();
                        attributesTable = new AttributesTable();
                        keys = new string[header.NumFields];
                        geometry = (Geometry)shapeFileDataReader.Geometry;

                        for (int i = 0; i < header.NumFields; i++)
                        {
                            fldDescriptor = header.Fields[i];
                            keys[i] = fldDescriptor.Name;
                            attributesTable.AddAttribute(fldDescriptor.Name, shapeFileDataReader.GetValue(i));
                        }

                        feature.Geometry = geometry;
                        feature.Attributes = attributesTable;
                        features.Add(feature);
                    }

                    bool areAllPoints = true;
                    foreach (Feature feat in features)
                    {
                        if (feat.Geometry.GeometryType.ToLower() != "point")
                        {
                            areAllPoints = false;
                            break;
                        }
                    }

                    //if all features are points
                    if (areAllPoints)
                    {
                        tmpPoints.Clear();

                        _Poly = new TtPolygon(1000 * polyCount + 10);

                        _Poly.Name = Path.GetFileNameWithoutExtension(file);

                        index = 0;

                        foreach (Feature feat in features)
                        {
                            //if features is only a point there should only be 1 coord
                            foreach (Coordinate coord in feat.Geometry.Coordinates)
                            {
                                gps = new GpsPoint();
                                gps.OnBnd = true;

                                gps.Index = index;
                                index++;

                                gps.MetaDefCN = _Meta.CN;

                                if (tmpPoints.Count > 0)
                                    gps.PID = PointNaming.NamePoint(tmpPoints.Last(), _Poly);
                                else
                                    gps.PID = PointNaming.NameFirstPoint(_Poly);

                                if (latlon)
                                {
                                    double x,y;

                                    TtUtils.LatLontoUTM(coord.Y, coord.X, _Meta.Zone, out y, out x);

                                    gps.UnAdjX = x;
                                    gps.UnAdjY = y;
                                }
                                else
                                {
                                    gps.UnAdjX = coord.X;
                                    gps.UnAdjY = coord.Y;
                                }

                                if (useElev)
                                {
                                    if (coord.Z != double.NaN)
                                    {
                                        if (elevFeet)
                                            gps.UnAdjZ = TtUtils.ConvertToMeters(coord.Z, Unit.FEET_TENTH);
                                        else
                                            gps.UnAdjZ = coord.Z;
                                    }
                                    else
                                        gps.UnAdjZ = 0;
                                }
                                else
                                    gps.UnAdjZ = 0;

                                gps.PolyCN = _Poly.CN;
                                gps.PolyName = _Poly.Name;

                                gps.GroupCN = Values.MainGroup.CN;
                                gps.GroupName = Values.MainGroup.Name;

                                tmpPoints.Add(gps);
                            }

                            _Points.AddRange(tmpPoints);
                        }

                        _Polygons.Add(_Poly.CN, _Poly);
                        polyCount++;
                    }
                    else //else get points out of each features
                    {
                        int fidInc = 0;

                        foreach (Feature feat in features)
                        {
                            tmpPoints.Clear();

                            _Poly = new TtPolygon(1000 * polyCount + 10);

                            if (features.Count < 2)
                                _Poly.Name = Path.GetFileNameWithoutExtension(file);
                            else
                                _Poly.Name = String.Format("{0}-{1}", fidInc++, Path.GetFileNameWithoutExtension(file));

                            #region Shape Desc Properties
                            if (useShapeProps)
                            {
                                object[] objs = feat.Attributes.GetValues();
                                string[] names = feat.Attributes.GetNames();
                                string objv;

                                for (int i = 0; i < feat.Attributes.Count; i++)
                                {
                                    if (objs[i] is string)
                                    {
                                        objv = (string)objs[i];

                                        if (objv.IsEmpty())
                                            continue;

                                        switch (names[i].ToLower())
                                        {
                                            case "description":
                                            case "comment":
                                            case "poly":
                                                if (_Poly.Description.IsEmpty())
                                                    _Poly.Description = objv;
                                                else
                                                    _Poly.Description = String.Format("{0} | {1}", _Poly.Description, objv);
                                                break;
                                            case "name":
                                            case "unit":
                                                _Poly.Name = objv;
                                                break;
                                        }
                                    }
                                }
                            }
                            #endregion

                            index = 0;

                            foreach (Coordinate coord in feat.Geometry.Coordinates)
                            {
                                gps = new GpsPoint();
                                gps.OnBnd = true;

                                gps.Index = index;
                                index++;

                                gps.MetaDefCN = _Meta.CN;

                                if (tmpPoints.Count > 0)
                                    gps.PID = PointNaming.NamePoint(tmpPoints.Last(), _Poly);
                                else
                                    gps.PID = PointNaming.NameFirstPoint(_Poly);

                                if (latlon)
                                {
                                    double x, y;

                                    TtUtils.LatLontoUTM(coord.Y, coord.X, _Meta.Zone, out y, out x);

                                    gps.UnAdjX = x;
                                    gps.UnAdjY = y;
                                }
                                else
                                {
                                    gps.UnAdjX = coord.X;
                                    gps.UnAdjY = coord.Y;
                                }

                                if (useElev)
                                {
                                    if (coord.Z == double.NaN)
                                    {
                                        if (elevFeet)
                                            gps.UnAdjZ = TtUtils.ConvertToMeters(coord.Z, Unit.FEET_TENTH);
                                        else
                                            gps.UnAdjZ = coord.Z;
                                    }
                                    else
                                        gps.UnAdjZ = 0;
                                }
                                else
                                    gps.UnAdjZ = 0;

                                gps.PolyCN = _Poly.CN;
                                gps.PolyName = _Poly.Name;

                                gps.GroupCN = Values.MainGroup.CN;
                                gps.GroupName = Values.MainGroup.Name;

                                tmpPoints.Add(gps);
                            }

                            _Points.AddRange(tmpPoints);
                            _Polygons.Add(_Poly.CN, _Poly);
                            polyCount++;
                        }
                    }

                    //Close and free up any resources
                    shapeFileDataReader.Close();
                    shapeFileDataReader.Dispose();
                }

                foreach (TtPolygon poly in _Polygons.Values)
                    dal.InsertPolygon(poly);

                dal.InsertPoints(_Points);

                PolygonAdjuster.Adjust(dal);
            }
            catch (Exception ex)
            {
                TtUtils.WriteError(ex.Message, "DataImport:ImportShapes", ex.StackTrace);

                return false;
            }

            return true;
        }