private void OnTopicToggleChange(bool isOn, WordCloudTopic topic) { // Delete old 3d labels if (activeTopic != null) { DeleteAll(activeTopic.activeItems); } // create 3d labels for each Survey result if (isOn) { activeTopic = topic; // TODO improve grouping algorithm var groupedSet = PseudoGroupIt(topic.topicItems); for (int i = 0; i < groupedSet.Count; ++i) { //if (!groupedSet[i].grouped) //{ var label = Instantiate(labelPrefab, labelsContainer, false); label.transform.name = groupedSet[i].stringLabel; label.text = groupedSet[i].stringLabel; label.fontSize = (int)(baseTextSize + groupedSet[i].size * textScale); Coordinate coords = groupedSet[i].coord; label.transform.localPosition = map.GetUnitsFromCoordinates(coords); // Check if coordinates is not 0,0. Missing coordinates value is often market as 0,0 in APIs if (coords.Latitude != 0 || coords.Longitude != 0) { activeTopic.activeItems.Add(new WordCloudItem(coords, label)); } //} } UpdateText(); UpdatePositions(activeTopic.activeItems); } else { activeTopic = null; } }
private void ClearUI() { // Delete 3D labels if (activeTopic != null) { DeleteAll(activeTopic.activeItems); activeTopic = null; } // Delete DB toggles foreach (var toggle in databaseToggles) { Destroy(toggle.gameObject); } databaseToggles.Clear(); // Delete topic containers foreach (var container in topicContainers) { Destroy(container.gameObject); } topicContainers.Clear(); }
private static WordCloudDatabase ParseDataFromAPI(string text, API setup) { var entriesDict = new Dictionary <string, List <GeolocatedValue> >(); // Init Dictionary foreach (var value in setup.valueFields) { entriesDict.Add(value, new List <GeolocatedValue>()); } var root = JSONNode.Parse(text); int missingCoords = 0; int invalidCoords = 0; int oobCoords = 0; bool hasValidValues = false; // Get coordinates from each node and pass the values for header from setup foreach (var nodes in root) { var nodesDict = nodes.Value; // Check if long and lat names are in API data if (!nodesDict.HasKey(setup.latitudeField) || !nodesDict.HasKey(setup.longitudeField)) { missingCoords++; continue; } var nodeLon = nodesDict.GetValueOrDefault(setup.longitudeField, null); var nodeLat = nodesDict.GetValueOrDefault(setup.latitudeField, null); if (!TryGetDouble(nodeLon, out double lon) || !TryGetDouble(nodeLat, out double lat)) { invalidCoords++; continue; } if (lon > GeoCalculator.MaxLongitude || lon < GeoCalculator.MinLatitude || lat > GeoCalculator.MaxLatitude || lat < GeoCalculator.MinLatitude) { oobCoords++; continue; } var coord = new Coordinate { Longitude = lon, Latitude = lat }; foreach (var valueField in setup.valueFields) { var node = nodesDict.GetValueOrDefault(valueField, null); if (node != null && !string.IsNullOrWhiteSpace(node.Value)) { hasValidValues = true; entriesDict[valueField].Add(new GeolocatedValue { value = node.Value, coord = coord }); } } } if (missingCoords > 0) { Debug.LogError(missingCoords + " missing coordinates in API: " + setup.name); return(null); } if (invalidCoords > 0) { Debug.LogWarning(invalidCoords + " invalid coordinates in API: " + setup.name); } if (oobCoords > 0) { Debug.LogWarning(oobCoords + " out-of-bound coordinates in API: " + setup.name); } if (!hasValidValues) { return(null); } // Create new database var database = new WordCloudDatabase(); database.name = setup.name; // Create topic items from entries foreach (var pair in entriesDict) { var topic = new WordCloudTopic(); topic.name = pair.Key; foreach (var entry in pair.Value) { topic.topicItems.Add(new TopicItem { coord = entry.coord, stringLabel = entry.value }); } database.topics.Add(topic); } return(database); }
private static WordCloudDatabase Parse(StreamReader sr, string filename) { WordCloudDatabase database2 = new WordCloudDatabase(); int LatColumn = -1; int LongColumn = -1; int range = 5; string marker = "*"; System.Random rnd = new System.Random(1); string line = sr.ReadLine(); MatchCollection matches = CsvHelper.regex.Matches(line); int headerCount = matches.Count; WordCloudTopic[] topics = new WordCloudTopic[headerCount]; for (int i = 0; i < headerCount; ++i) { string headerCell = matches[i].Groups[2].Value.Trim(); bool ignore = headerCell.StartsWith(marker); if (ignore) { headerCell = headerCell.Substring(1); } // Check for column position of Latitude and Longtitude if (headerCell.EqualsIgnoreCase("latitude") || headerCell.EqualsIgnoreCase("lat") || headerCell.EqualsIgnoreCase("USULAN_LAT")) { LatColumn = i; } else if (headerCell.EqualsIgnoreCase("longitude") || headerCell.EqualsIgnoreCase("long") || headerCell.EqualsIgnoreCase("lng") || headerCell.EqualsIgnoreCase("USULAN_LONG")) { LongColumn = i; } else if (!ignore) { var topic = new WordCloudTopic(); topic.name = headerCell; topics[i] = topic; database2.topics.Add(topic); } } if (LatColumn == -1 || LongColumn == -1) { Debug.LogError("File " + filename + " doesn't have longitude/latitude headers"); return(null); } while ((line = sr.ReadLine()) != null) { matches = CsvHelper.regex.Matches(line); while (matches.Count < headerCount) { string extraLine = sr.ReadLine(); if (extraLine == null) { break; } line += extraLine; matches = CsvHelper.regex.Matches(line); } if (string.IsNullOrEmpty(matches[0].Groups[2].Value)) { continue; } double latitude = 0; double longtitude = 0; if (!double.TryParse(matches[LatColumn].Groups[2].Value, out latitude) || !double.TryParse(matches[LongColumn].Groups[2].Value, out longtitude)) { continue; } double randomLat = rnd.Next(-range, range) * 0.0001; double randomLong = rnd.Next(-range, range) * 0.0001; int count = matches.Count; for (int i = 0; i < count; ++i) { var topic = topics[i]; if (topic == null) { continue; } // split if multiple answers in survey separated by ',' or by new line var cell = matches[i].Groups[2].Value; var item = cell.Split(new string[] { "\n", "\r\n", ",", "#" }, System.StringSplitOptions.RemoveEmptyEntries); for (int j = 0; j < item.Length; ++j) { var text = item[j].Trim(); if (!string.IsNullOrEmpty(text)) { TopicItem topicItem = new TopicItem(); // Randomize position to protect privacy and avoid same position topicItem.coord.Latitude = latitude + randomLat; topicItem.coord.Longitude = longtitude + randomLong; topicItem.stringLabel = text; topicItem.size = 1; topic.topicItems.Add(topicItem); } } } } // Assing id based on string similarity Dictionary <string, int> idCheck = new Dictionary <string, int>(); foreach (var topic in database2.topics) { int id = 0; foreach (var dataItemA in topic.topicItems) { string idHelp = dataItemA.stringLabel; if (idCheck.ContainsKey(idHelp)) { dataItemA.stringId = idCheck[idHelp]; } else { dataItemA.stringId = ++id; idCheck.Add(idHelp, dataItemA.stringId); } } } return(database2); }